From dd8b2eadab12965d232640449b1d1c9f2484238c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 30 Nov 2012 17:36:40 -0800 Subject: ao-tools: Add ao-sky-flash to update GPS firmware This uses a new feature of AltOS to directly connect the GPS chip to the USB link to reprogram the former. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/ao-sky-flash/Makefile.am | 18 ++ .../STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin | Bin 0 -> 318000 bytes ....10-01.07.23_balloon_CRC_7082_9600_20120913.bin | Bin 0 -> 303344 bytes ao-tools/ao-sky-flash/ao-sky-flash.1 | 85 +++++ ao-tools/ao-sky-flash/sky_bin.c | 75 +++++ ao-tools/ao-sky-flash/sky_debug.c | 111 +++++++ ao-tools/ao-sky-flash/sky_flash.c | 259 +++++++++++++++ ao-tools/ao-sky-flash/sky_flash.h | 67 ++++ ao-tools/ao-sky-flash/sky_serial.c | 259 +++++++++++++++ ao-tools/ao-sky-flash/sky_srec.c | 60 ++++ ao-tools/ao-sky-flash/srec_115200.bin | 346 +++++++++++++++++++++ ao-tools/ao-sky-flash/srec_9600.bin | 346 +++++++++++++++++++++ 13 files changed, 1627 insertions(+), 1 deletion(-) create mode 100644 ao-tools/ao-sky-flash/Makefile.am create mode 100644 ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin create mode 100644 ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin create mode 100644 ao-tools/ao-sky-flash/ao-sky-flash.1 create mode 100644 ao-tools/ao-sky-flash/sky_bin.c create mode 100644 ao-tools/ao-sky-flash/sky_debug.c create mode 100644 ao-tools/ao-sky-flash/sky_flash.c create mode 100644 ao-tools/ao-sky-flash/sky_flash.h create mode 100644 ao-tools/ao-sky-flash/sky_serial.c create mode 100644 ao-tools/ao-sky-flash/sky_srec.c create mode 100644 ao-tools/ao-sky-flash/srec_115200.bin create mode 100644 ao-tools/ao-sky-flash/srec_9600.bin (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 257fdaec..871b8205 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem +SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash diff --git a/ao-tools/ao-sky-flash/Makefile.am b/ao-tools/ao-sky-flash/Makefile.am new file mode 100644 index 00000000..f6c5089a --- /dev/null +++ b/ao-tools/ao-sky-flash/Makefile.am @@ -0,0 +1,18 @@ +bin_PROGRAMS=ao-sky-flash + +AM_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 diff --git a/ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin b/ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin new file mode 100644 index 00000000..c698add2 Binary files /dev/null and b/ao-tools/ao-sky-flash/STI_01.04.42-01.10.23_4x_9600_Bin_20100901.bin differ diff --git a/ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin b/ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin new file mode 100644 index 00000000..9e256897 Binary files /dev/null and b/ao-tools/ao-sky-flash/STI_01.06.10-01.07.23_balloon_CRC_7082_9600_20120913.bin differ diff --git a/ao-tools/ao-sky-flash/ao-sky-flash.1 b/ao-tools/ao-sky-flash/ao-sky-flash.1 new file mode 100644 index 00000000..d61c9c9d --- /dev/null +++ b/ao-tools/ao-sky-flash/ao-sky-flash.1 @@ -0,0 +1,85 @@ +.\" +.\" Copyright © 2009 Keith Packard +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; 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 diff --git a/ao-tools/ao-sky-flash/sky_bin.c b/ao-tools/ao-sky-flash/sky_bin.c new file mode 100644 index 00000000..e693c892 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_bin.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "sky_flash.h" +#include +#include + +#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; + } + + printf ("computing checksum...\n"); fflush(stdout); + /* Compute checksum, figure out how long the file */ + cksum = 0; + while ((c = getc(file)) != EOF) + cksum += (unsigned char) c; + size = ftell(file); + rewind(file); + printf ("checksum: %d\n", cksum); fflush(stdout); + + sprintf(message, "BINSIZE = %d 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; + printf ("write %ld of %ld ", pos + count, size); fflush(stdout); + pos += count; + ret = skytraq_cmd_wait(fd, buf, count, "OK", 20000); + if (ret < 0) + return ret; + } + return skytraq_waitstatus(fd, "END", 30000); +} diff --git a/ao-tools/ao-sky-flash/sky_debug.c b/ao-tools/ao-sky-flash/sky_debug.c new file mode 100644 index 00000000..32571f0e --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_debug.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#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; +} diff --git a/ao-tools/ao-sky-flash/sky_flash.c b/ao-tools/ao-sky-flash/sky_flash.c new file mode 100644 index 00000000..55cb2cb6 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_flash.c @@ -0,0 +1,259 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "sky_flash.h" +#include +#include +#include +#include +#include +#include +#include "cc.h" + +static const struct option options[] = { + { .name = "tty", .has_arg = 1, .val = 'T' }, + { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "loader", .has_arg = 1, .val = 'l' }, + { .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 ]\n" + " [--device ]\n" + " [--loader ]\n" + " [--firmware ]\n" + " [--query]\n" + " [--quiet]\n" + " [--raw]\n", program); + exit(1); +} + +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; +} + +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, cksum_read; + 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; + char buf[512]; + int ret; + FILE *input; + long size; + unsigned char cksum; + int c; + char message[1024]; + char *tty = NULL; + char *device = NULL; + char *loader = "srec_115200.bin"; + 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 'l': + loader = 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; +} diff --git a/ao-tools/ao-sky-flash/sky_flash.h b/ao-tools/ao-sky-flash/sky_flash.h new file mode 100644 index 00000000..77f4c742 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_flash.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* 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 char *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_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); diff --git a/ao-tools/ao-sky-flash/sky_serial.c b/ao-tools/ao-sky-flash/sky_serial.c new file mode 100644 index 00000000..4aeb1458 --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_serial.c @@ -0,0 +1,259 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#define _BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include "sky_flash.h" +#include +#include +#include +#include +#include + +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 char *data, int len) +{ + const char *d = data; + int r; + int us; + + while (len) { + int this_time = len; + if (this_time > 128) + this_time = 128; + if (this_time < 70) { + skytraq_dbg_printf (0, "%4d: ", this_time); + skytraq_dbg_buf(0, data, this_time); + } else { + skytraq_dbg_printf (0, "%d bytes (%d remain)", this_time, len); + } + fflush(stdout); + r = write(fd, data, this_time); + if (r <= 0) + return r; + us = r * US_PER_CHAR; + 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; + 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); +} diff --git a/ao-tools/ao-sky-flash/sky_srec.c b/ao-tools/ao-sky-flash/sky_srec.c new file mode 100644 index 00000000..6d00f58c --- /dev/null +++ b/ao-tools/ao-sky-flash/sky_srec.c @@ -0,0 +1,60 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "sky_flash.h" +#include +#include + +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; +} diff --git a/ao-tools/ao-sky-flash/srec_115200.bin b/ao-tools/ao-sky-flash/srec_115200.bin new file mode 100644 index 00000000..8ea8e7cd --- /dev/null +++ b/ao-tools/ao-sky-flash/srec_115200.bin @@ -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 diff --git a/ao-tools/ao-sky-flash/srec_9600.bin b/ao-tools/ao-sky-flash/srec_9600.bin new file mode 100644 index 00000000..9a29ab1b --- /dev/null +++ b/ao-tools/ao-sky-flash/srec_9600.bin @@ -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 -- cgit v1.2.3 From 5f6b3790667d9b92370b4fe0dad5626929fea2ba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 30 Nov 2012 20:51:47 -0800 Subject: altos: Make skytraq reflashing code try both 9600 and 4800 baud This lets it communicate with the ROM code which boots at 4800 baud instead of 9600 baud. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/lib/Makefile.am | 1 + ao-tools/lib/cc.h | 116 +++++++++++++++++++++++ configure.ac | 1 + src/drivers/ao_gps_skytraq.c | 6 ++ src/test/Makefile | 2 +- src/test/ao_flight_test.c | 213 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 339 insertions(+), 2 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 871b8205..4cf1f382 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash +SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash ao-mega diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index 1f8f2e42..a664d083 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -34,6 +34,7 @@ libao_tools_a_SOURCES = \ cc-telem.c \ cc-telemetry.c \ cc-telemetry.h \ + cc-mega.c \ cp-usb-async.c \ cp-usb-async.h \ i0.c \ diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index 6257ee44..625540bb 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -269,6 +269,122 @@ struct cc_telem { int cc_telem_parse(const char *input_line, struct cc_telem *telem); +struct ao_log_mega { + char type; /* 0 */ + uint8_t is_config; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + int16_t ground_accel; /* 6 */ + uint32_t ground_pres; /* 8 */ + } flight; /* 12 */ + /* AO_LOG_STATE */ + struct { + uint16_t state; + uint16_t reason; + } state; + /* AO_LOG_SENSOR */ + struct { + uint32_t pres; /* 4 */ + uint32_t temp; /* 8 */ + int16_t accel_x; /* 12 */ + int16_t accel_y; /* 14 */ + int16_t accel_z; /* 16 */ + int16_t gyro_x; /* 18 */ + int16_t gyro_y; /* 20 */ + int16_t gyro_z; /* 22 */ + int16_t mag_x; /* 24 */ + int16_t mag_y; /* 26 */ + int16_t mag_z; /* 28 */ + int16_t accel; /* 30 */ + } sensor; /* 32 */ + /* AO_LOG_TEMP_VOLT */ + struct { + int16_t v_batt; /* 4 */ + int16_t v_pbatt; /* 6 */ + int16_t n_sense; /* 8 */ + int16_t sense[10]; /* 10 */ + } volt; /* 30 */ + /* AO_LOG_GPS_TIME */ + struct { + int32_t latitude; /* 4 */ + int32_t longitude; /* 8 */ + int16_t altitude; /* 12 */ + uint8_t hour; /* 14 */ + uint8_t minute; /* 15 */ + uint8_t second; /* 16 */ + uint8_t flags; /* 17 */ + uint8_t year; /* 18 */ + uint8_t month; /* 19 */ + uint8_t day; /* 20 */ + uint8_t pad; /* 21 */ + } gps; /* 22 */ + /* AO_LOG_GPS_SAT */ + struct { + uint16_t channels; /* 4 */ + struct { + uint8_t svid; + uint8_t c_n; + } sats[12]; /* 6 */ + } gps_sat; /* 30 */ + + struct { + uint32_t kind; + int32_t data[6]; + } config_int; + + struct { + uint32_t kind; + char string[24]; + } config_str; + + /* Raw bytes */ + uint8_t bytes[28]; + } u; +}; + +#define AO_CONFIG_CONFIG 1 +#define AO_CONFIG_MAIN 2 +#define AO_CONFIG_APOGEE 3 +#define AO_CONFIG_LOCKOUT 4 +#define AO_CONFIG_FREQUENCY 5 +#define AO_CONFIG_RADIO_ENABLE 6 +#define AO_CONFIG_ACCEL_CAL 7 +#define AO_CONFIG_RADIO_CAL 8 +#define AO_CONFIG_MAX_LOG 9 +#define AO_CONFIG_IGNITE_MODE 10 +#define AO_CONFIG_PAD_ORIENTATION 11 +#define AO_CONFIG_SERIAL_NUMBER 12 +#define AO_CONFIG_LOG_FORMAT 13 +#define AO_CONFIG_MS5607_RESERVED 14 +#define AO_CONFIG_MS5607_SENS 15 +#define AO_CONFIG_MS5607_OFF 16 +#define AO_CONFIG_MS5607_TCS 17 +#define AO_CONFIG_MS5607_TCO 18 +#define AO_CONFIG_MS5607_TREF 19 +#define AO_CONFIG_MS5607_TEMPSENS 20 +#define AO_CONFIG_MS5607_CRC 21 + + +#define AO_LOG_FLIGHT 'F' +#define AO_LOG_SENSOR 'A' +#define AO_LOG_TEMP_VOLT 'T' +#define AO_LOG_DEPLOY 'D' +#define AO_LOG_STATE 'S' +#define AO_LOG_GPS_TIME 'G' +#define AO_LOG_GPS_LAT 'N' +#define AO_LOG_GPS_LON 'W' +#define AO_LOG_GPS_ALT 'H' +#define AO_LOG_GPS_SAT 'V' +#define AO_LOG_GPS_DATE 'Y' + +#define AO_LOG_CONFIG 'c' + +int +cc_mega_parse(const char *input_line, struct ao_log_mega *l); + #ifndef TRUE #define TRUE 1 #define FALSE 0 diff --git a/configure.ac b/configure.ac index 0fcd97e2..ad10ac3c 100644 --- a/configure.ac +++ b/configure.ac @@ -164,6 +164,7 @@ ao-tools/ao-telem/Makefile ao-tools/ao-stmload/Makefile ao-tools/ao-send-telem/Makefile ao-tools/ao-sky-flash/Makefile +ao-tools/ao-mega/Makefile ao-utils/Makefile src/Version ]) diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index b7dc0a86..d637a602 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -515,7 +515,13 @@ gps_update(void) __reentrant ao_timer_set_adc_interval(0); #endif ao_skytraq_sendstruct(ao_gps_115200); + ao_delay(AO_MS_TO_TICKS(500)); + ao_gps_set_speed(AO_SERIAL_SPEED_4800); + ao_delay(AO_MS_TO_TICKS(500)); + ao_skytraq_sendstruct(ao_gps_115200); + ao_delay(AO_MS_TO_TICKS(500)); ao_gps_set_speed(AO_SERIAL_SPEED_115200); + ao_delay(AO_MS_TO_TICKS(500)); /* It's a binary protocol; abandon attempts to escape */ for (;;) diff --git a/src/test/Makefile b/src/test/Makefile index 44cee904..0dcdc949 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -29,7 +29,7 @@ ao_flight_test_accel: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kal cc $(CFLAGS) -o $@ -DFORCE_ACCEL=1 ao_flight_test.c ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c $(INCS) - cc -DMEGAMETRUM=1 $(CFLAGS) -o $@ $< + cc -DMEGAMETRUM=1 $(CFLAGS) -o $@ $< -lm ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h cc $(CFLAGS) -o $@ $< diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 7180f02d..acdf4d92 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -547,6 +547,202 @@ int32(uint8_t *bytes, int off) static int log_format; +#if MEGAMETRUM + +static double +ao_vec_norm(double x, double y, double z) +{ + return x*x + y*y + z*z; +} + +static void +ao_vec_normalize(double *x, double *y, double *z) +{ + double scale = 1/sqrt(ao_vec_norm(*x, *y, *z)); + + *x *= scale; + *y *= scale; + *z *= scale; +} + +struct ao_quat { + double q0, q1, q2, q3; +}; + +static void +ao_quat_mul(struct ao_quat *r, struct ao_quat *a, struct ao_quat *b) +{ + r->q0 = a->q0 * b->q0 - a->q1 * b->q1 - a->q2 * b->q2 - a->q3 * b->q3; + r->q1 = a->q0 * b->q1 + a->q1 * b->q0 + a->q2 * b->q3 - a->q3 * b->q2; + r->q2 = a->q0 * b->q2 - a->q1 * b->q3 + a->q2 * b->q0 + a->q3 * b->q1; + r->q3 = a->q0 * b->q3 + a->q1 * b->q2 - a->q2 * b->q1 + a->q3 * b->q0; +} + +#if 0 +static void +ao_quat_scale(struct ao_quat *r, struct ao_quat *a, double s) +{ + r->q0 = a->q0 * s; + r->q1 = a->q1 * s; + r->q2 = a->q2 * s; + r->q3 = a->q3 * s; +} +#endif + +static void +ao_quat_conj(struct ao_quat *r, struct ao_quat *a) +{ + r->q0 = a->q0; + r->q1 = -a->q1; + r->q2 = -a->q2; + r->q3 = -a->q3; +} + +static void +ao_quat_rot(struct ao_quat *r, struct ao_quat *a, struct ao_quat *q) +{ + struct ao_quat t; + struct ao_quat c; + ao_quat_mul(&t, q, a); + ao_quat_conj(&c, q); + ao_quat_mul(r, &t, &c); +} + +static void +ao_quat_from_angle(struct ao_quat *r, + double x_rad, + double y_rad, + double z_rad) +{ + double angle = sqrt (x_rad * x_rad + y_rad * y_rad + z_rad * z_rad); + double s = sin(angle/2); + double c = cos(angle/2); + + r->q0 = c; + r->q1 = x_rad * s / angle; + r->q2 = y_rad * s / angle; + r->q3 = z_rad * s / angle; +} + +static void +ao_quat_from_vector(struct ao_quat *r, double x, double y, double z) +{ + ao_vec_normalize(&x, &y, &z); + double x_rad = atan2(z, y); + double y_rad = atan2(x, z); + double z_rad = atan2(y, x); + + ao_quat_from_angle(r, x_rad, y_rad, z_rad); +} + +static double +ao_quat_norm(struct ao_quat *a) +{ + return (a->q0 * a->q0 + + a->q1 * a->q1 + + a->q2 * a->q2 + + a->q3 * a->q3); +} + +static void +ao_quat_normalize(struct ao_quat *a) +{ + double norm = ao_quat_norm(a); + + if (norm) { + double m = 1/sqrt(norm); + + a->q0 *= m; + a->q1 *= m; + a->q2 *= m; + a->q3 *= m; + } +} + +static struct ao_quat ao_up, ao_current; +static struct ao_quat ao_orient; +static int ao_orient_tick; + +void +set_orientation(double x, double y, double z, int tick) +{ + struct ao_quat t; + + printf ("set_orientation %g %g %g\n", x, y, z); + ao_quat_from_vector(&ao_orient, x, y, z); + ao_up.q1 = ao_up.q2 = 0; + ao_up.q0 = ao_up.q3 = sqrt(2)/2; + ao_orient_tick = tick; + + ao_orient.q0 = 1; + ao_orient.q1 = 0; + ao_orient.q2 = 0; + ao_orient.q3 = 0; + + printf ("orient (%g) %g %g %g up (%g) %g %g %g\n", + ao_orient.q0, + ao_orient.q1, + ao_orient.q2, + ao_orient.q3, + ao_up.q0, + ao_up.q1, + ao_up.q2, + ao_up.q3); + + ao_quat_rot(&t, &ao_up, &ao_orient); + printf ("pad orient (%g) %g %g %g\n", + t.q0, + t.q1, + t.q2, + t.q3); + +} + +void +update_orientation (double rate_x, double rate_y, double rate_z, int tick) +{ + struct ao_quat q_dot; + double lambda; + double dt = (tick - ao_orient_tick) / 100.0; + + ao_orient_tick = tick; + +// lambda = 1 - ao_quat_norm(&ao_orient); + lambda = 0; + + q_dot.q0 = -0.5 * (ao_orient.q1 * rate_x + ao_orient.q2 * rate_y + ao_orient.q3 * rate_z) + lambda * ao_orient.q0; + q_dot.q1 = 0.5 * (ao_orient.q0 * rate_x + ao_orient.q2 * rate_z - ao_orient.q3 * rate_y) + lambda * ao_orient.q1; + q_dot.q2 = 0.5 * (ao_orient.q0 * rate_y + ao_orient.q3 * rate_x - ao_orient.q1 * rate_z) + lambda * ao_orient.q2; + q_dot.q3 = 0.5 * (ao_orient.q0 * rate_z + ao_orient.q1 * rate_y - ao_orient.q2 * rate_x) + lambda * ao_orient.q3; + + printf ("update_orientation %g %g %g (%g s)\n", rate_x, rate_y, rate_z, dt); + printf ("q_dot (%g) %g %g %g\n", + q_dot.q0, + q_dot.q1, + q_dot.q2, + q_dot.q3); + + ao_orient.q0 += q_dot.q0 * dt; + ao_orient.q1 += q_dot.q1 * dt; + ao_orient.q2 += q_dot.q2 * dt; + ao_orient.q3 += q_dot.q3 * dt; + + ao_quat_normalize(&ao_orient); + + ao_quat_rot(&ao_current, &ao_up, &ao_orient); + + printf ("orient (%g) %g %g %g current (%g) %g %g %g\n", + ao_orient.q0, + ao_orient.q1, + ao_orient.q2, + ao_orient.q3, + ao_current.q0, + ao_current.q1, + ao_current.q2, + ao_current.q3); +} +#endif + void ao_sleep(void *wchan) { @@ -635,6 +831,21 @@ ao_sleep(void *wchan) f(gyro_x); f(gyro_y); f(gyro_z); + + double accel_x = ao_mpu6000_accel(ao_ground_mpu6000.accel_x); + double accel_y = ao_mpu6000_accel(ao_ground_mpu6000.accel_y); + double accel_z = ao_mpu6000_accel(ao_ground_mpu6000.accel_z); + + /* X and Y are in the ground plane, arbitraryily picked as MPU X and Z axes + * Z is normal to the ground, the MPU y axis + */ + set_orientation(accel_x, accel_z, accel_y, tick); + } else { + double rate_x = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_x - ao_ground_mpu6000.gyro_x); + double rate_y = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_y - ao_ground_mpu6000.gyro_y); + double rate_z = ao_mpu6000_gyro(ao_data_static.mpu6000.gyro_z - ao_ground_mpu6000.gyro_z); + + update_orientation(rate_x, rate_z, rate_y, tick); } ao_records_read++; ao_insert(); @@ -779,6 +990,8 @@ ao_sleep(void *wchan) continue; #if MEGAMETRUM + (void) a; + (void) b; #else switch (type) { case 'F': -- cgit v1.2.3 From d4d5d411679d074295d4722f4887fd1cf4f0906c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 4 Dec 2012 01:30:39 -0800 Subject: ao-sky-flash: Clean up debug printfs a bit This makes debugging output a bit cleaner Signed-off-by: Keith Packard --- ao-tools/ao-sky-flash/sky_bin.c | 4 +--- ao-tools/ao-sky-flash/sky_serial.c | 10 ++++------ 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-sky-flash/sky_bin.c b/ao-tools/ao-sky-flash/sky_bin.c index e693c892..04cfec35 100644 --- a/ao-tools/ao-sky-flash/sky_bin.c +++ b/ao-tools/ao-sky-flash/sky_bin.c @@ -40,14 +40,12 @@ skytraq_send_bin(int fd, const char *filename) return -1; } - printf ("computing checksum...\n"); fflush(stdout); /* Compute checksum, figure out how long the file */ cksum = 0; while ((c = getc(file)) != EOF) cksum += (unsigned char) c; size = ftell(file); rewind(file); - printf ("checksum: %d\n", cksum); fflush(stdout); sprintf(message, "BINSIZE = %d Checksum = %d Loopnumber = %d ", size, cksum, 1); @@ -65,7 +63,7 @@ skytraq_send_bin(int fd, const char *filename) } if (count == 0) break; - printf ("write %ld of %ld ", pos + count, size); fflush(stdout); + skytraq_dbg_printf (0, "%7d of %7d ", pos + count, size); pos += count; ret = skytraq_cmd_wait(fd, buf, count, "OK", 20000); if (ret < 0) diff --git a/ao-tools/ao-sky-flash/sky_serial.c b/ao-tools/ao-sky-flash/sky_serial.c index 4aeb1458..7230bf8c 100644 --- a/ao-tools/ao-sky-flash/sky_serial.c +++ b/ao-tools/ao-sky-flash/sky_serial.c @@ -103,16 +103,14 @@ skytraq_write(int fd, const char *data, int len) int r; int us; + 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; - if (this_time < 70) { - skytraq_dbg_printf (0, "%4d: ", this_time); - skytraq_dbg_buf(0, data, this_time); - } else { - skytraq_dbg_printf (0, "%d bytes (%d remain)", this_time, len); - } + skytraq_dbg_printf(0, "."); fflush(stdout); r = write(fd, data, this_time); if (r <= 0) -- cgit v1.2.3 From 1f52e8afce514a6b943c92aaa6d7189d11d9fe76 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 4 Dec 2012 01:34:03 -0800 Subject: ao-tools. Oops, let 'ao-mega' slip into build. This is a tool to parse ao-mega eeprom files; not sure it'll be that useful, and it's certainly not usable *yet*. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/lib/Makefile.am | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 4cf1f382..871b8205 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1 +1 @@ -SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash ao-mega +SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index a664d083..1f8f2e42 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -34,7 +34,6 @@ libao_tools_a_SOURCES = \ cc-telem.c \ cc-telemetry.c \ cc-telemetry.h \ - cc-mega.c \ cp-usb-async.c \ cp-usb-async.h \ i0.c \ -- cgit v1.2.3 From 3605e97ee918b3f87e4c471906f708c3ea027eef Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 3 Mar 2013 16:53:52 -0800 Subject: ao-tools: Add ao-dumpflash program This program dumps the entire flash contents of an AltOS device to allow for external analysis. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 4 +- ao-tools/ao-dumpflash/.gitignore | 1 + ao-tools/ao-dumpflash/Makefile.am | 12 +++ ao-tools/ao-dumpflash/ao-dumpflash.1 | 71 ++++++++++++++ ao-tools/ao-dumpflash/ao-dumpflash.c | 175 +++++++++++++++++++++++++++++++++++ ao-tools/lib/cc-usb.c | 7 +- ao-tools/lib/cc-usb.h | 2 +- ao-tools/lib/ccdbg-flash.c | 5 - configure.ac | 1 + 9 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 ao-tools/ao-dumpflash/.gitignore create mode 100644 ao-tools/ao-dumpflash/Makefile.am create mode 100644 ao-tools/ao-dumpflash/ao-dumpflash.1 create mode 100644 ao-tools/ao-dumpflash/ao-dumpflash.c (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 871b8205..139eea3f 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1 +1,3 @@ -SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash +SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ + ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ + ao-dumpflash diff --git a/ao-tools/ao-dumpflash/.gitignore b/ao-tools/ao-dumpflash/.gitignore new file mode 100644 index 00000000..bbce511a --- /dev/null +++ b/ao-tools/ao-dumpflash/.gitignore @@ -0,0 +1 @@ +ao-dumpflash diff --git a/ao-tools/ao-dumpflash/Makefile.am b/ao-tools/ao-dumpflash/Makefile.am new file mode 100644 index 00000000..db99f5ae --- /dev/null +++ b/ao-tools/ao-dumpflash/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-dumpflash + +AM_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 diff --git a/ao-tools/ao-dumpflash/ao-dumpflash.1 b/ao-tools/ao-dumpflash/ao-dumpflash.1 new file mode 100644 index 00000000..07a08ba8 --- /dev/null +++ b/ao-tools/ao-dumpflash/ao-dumpflash.1 @@ -0,0 +1,71 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; 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 diff --git a/ao-tools/ao-dumpflash/ao-dumpflash.c b/ao-tools/ao-dumpflash/ao-dumpflash.c new file mode 100644 index 00000000..3cd21e66 --- /dev/null +++ b/ao-tools/ao-dumpflash/ao-dumpflash.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2009 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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 +#include +#include +#include +#include +#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 ] [--device ] [--remote] [--frequency ] [--call ]\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; + char *filename; + int serial_number = 0; + int freq = 434550; + char *call = "N0CALL"; + int flight = 0; + char cmd; + int block; + int addr; + int received_addr; + int data[8]; + int done; + int i; + int column; + int remote = 0; + int any_valid; + int invalid; + int storage_size = 0; + char *out_name; + + 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); +} diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index 1580c6d9..9f07e662 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -375,11 +375,12 @@ cc_usb_reset(struct cc_usb *cc) } void -cc_usb_open_remote(struct cc_usb *cc, int channel) +cc_usb_open_remote(struct cc_usb *cc, int freq, char *call) { if (!cc->remote) { - printf ("channel %d\n", channel); - cc_usb_printf(cc, "\nc r %d\np\nE 0\n", channel); + fprintf (stderr, "freq %dkHz\n", freq); + fprintf (stderr, "call %s\n", call); + cc_usb_printf(cc, "\nc F %d\nc c %s\np\nE 0\n", freq, call); do { cc->in_count = cc->in_pos = 0; _cc_usb_sync(cc, 100); diff --git a/ao-tools/lib/cc-usb.h b/ao-tools/lib/cc-usb.h index d3539281..e90e1195 100644 --- a/ao-tools/lib/cc-usb.h +++ b/ao-tools/lib/cc-usb.h @@ -63,7 +63,7 @@ void cc_usb_printf(struct cc_usb *cc, char *format, ...); void -cc_usb_open_remote(struct cc_usb *cc, int channel); +cc_usb_open_remote(struct cc_usb *cc, int freq, char *call); void cc_usb_close_remote(struct cc_usb *cc); diff --git a/ao-tools/lib/ccdbg-flash.c b/ao-tools/lib/ccdbg-flash.c index 3e672985..1b46870b 100644 --- a/ao-tools/lib/ccdbg-flash.c +++ b/ao-tools/lib/ccdbg-flash.c @@ -240,7 +240,6 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) uint8_t ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) { - uint16_t offset; uint16_t flash_prog; uint16_t flash_len; uint8_t fwt; @@ -249,7 +248,6 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) uint16_t flash_words; uint8_t flash_words_high, flash_words_low; uint16_t ram_addr; - uint16_t pc; uint8_t status; uint16_t remain, this_time, start; uint8_t verify[0x400]; @@ -284,8 +282,6 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) if (this_time > 0x400) this_time = 0x400; - offset = ram_addr - (image->address + start); - ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr); ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); #if 0 @@ -319,7 +315,6 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words_low); ccdbg_set_pc(dbg, flash_prog); - pc = ccdbg_get_pc(dbg); ccdbg_debug(CC_DEBUG_FLASH, "Flashing %d bytes at 0x%04x\n", this_time, flash_addr); status = ccdbg_resume(dbg); diff --git a/configure.ac b/configure.ac index 448df6a4..9e5dcaa7 100644 --- a/configure.ac +++ b/configure.ac @@ -181,6 +181,7 @@ ao-tools/ao-telem/Makefile ao-tools/ao-stmload/Makefile ao-tools/ao-send-telem/Makefile ao-tools/ao-sky-flash/Makefile +ao-tools/ao-dumpflash/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From 9b460d38bc2685bca7f530b7749c0e0381f6264c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Mar 2013 20:39:31 -0800 Subject: ao-tools/lib: Add cc_telemetry_unparse This takes a telemetry structure and generates a string version Signed-off-by: Keith Packard --- ao-tools/lib/cc-telemetry.c | 30 ++++++++++++++++++++++++++++++ ao-tools/lib/cc-telemetry.h | 12 ++++++++++++ 2 files changed, 42 insertions(+) (limited to 'ao-tools') diff --git a/ao-tools/lib/cc-telemetry.c b/ao-tools/lib/cc-telemetry.c index 99da2680..88da7f03 100644 --- a/ao-tools/lib/cc-telemetry.c +++ b/ao-tools/lib/cc-telemetry.c @@ -60,3 +60,33 @@ cc_telemetry_parse(const char *input_line, union ao_telemetry_all *telemetry) memcpy(telemetry, hex+1, 34); return TRUE; } + +uint8_t +cc_telemetry_cksum(const union ao_telemetry_all *telemetry) +{ + const uint8_t *x = (const uint8_t *) telemetry; + int i; + uint8_t sum = 0x5a; + for (i = 0; i < 34; i++) + sum += x[i]; + return sum; +} + +void +cc_telemetry_unparse(const union ao_telemetry_all *telemetry, char output_line[CC_TELEMETRY_BUFSIZE]) +{ + uint8_t hex[36]; + int i; + int p; + + hex[0] = 34; + memcpy(hex+1, telemetry, 34); + hex[35] = cc_telemetry_cksum(telemetry); + strcpy(output_line, "TELEM "); + p = strlen(output_line); + for (i = 0; i < 36; i++) { + sprintf(output_line + p, "%02x", hex[i]); + p += 2; + } +} + diff --git a/ao-tools/lib/cc-telemetry.h b/ao-tools/lib/cc-telemetry.h index e849cd3b..9a5be49f 100644 --- a/ao-tools/lib/cc-telemetry.h +++ b/ao-tools/lib/cc-telemetry.h @@ -237,7 +237,19 @@ union ao_telemetry_all { struct ao_telemetry_baro baro; }; +#define CC_TELEMETRY_HEADER "TELEM" + +/* "TELEM " 1 byte length 32 data bytes 1 rssi 1 status 1 checksum 1 null */ + +#define CC_TELEMETRY_BUFSIZE (6 + (1 + 32 + 3) * 2 + 1) + int cc_telemetry_parse(const char *input_line, union ao_telemetry_all *telemetry); +uint8_t +cc_telemetry_cksum(const union ao_telemetry_all *telemetry); + +void +cc_telemetry_unparse(const union ao_telemetry_all *telemetry, char output_line[CC_TELEMETRY_BUFSIZE]); + #endif -- cgit v1.2.3 From 72c5b1429bdfd6e9d2185bad7d0adb281fdf659a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Mar 2013 20:40:52 -0800 Subject: ao-tools: Add ao-edit-telem This lets you edit a telemetry file. The only current editing available is to change the pad location, allowing a flight to be replayed anywhere in the world. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/ao-edit-telem/Makefile.am | 12 +++ ao-tools/ao-edit-telem/ao-edit-telem.1 | 33 ++++++ ao-tools/ao-edit-telem/ao-edit-telem.c | 192 +++++++++++++++++++++++++++++++++ configure.ac | 1 + 5 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 ao-tools/ao-edit-telem/Makefile.am create mode 100644 ao-tools/ao-edit-telem/ao-edit-telem.1 create mode 100644 ao-tools/ao-edit-telem/ao-edit-telem.c (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 139eea3f..e4df2e63 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,3 +1,3 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ - ao-dumpflash + ao-dumpflash ao-edit-telem diff --git a/ao-tools/ao-edit-telem/Makefile.am b/ao-tools/ao-edit-telem/Makefile.am new file mode 100644 index 00000000..c5965c47 --- /dev/null +++ b/ao-tools/ao-edit-telem/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-edit-telem + +AM_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 diff --git a/ao-tools/ao-edit-telem/ao-edit-telem.1 b/ao-tools/ao-edit-telem/ao-edit-telem.1 new file mode 100644 index 00000000..8f125878 --- /dev/null +++ b/ao-tools/ao-edit-telem/ao-edit-telem.1 @@ -0,0 +1,33 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; 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=] +[\--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 diff --git a/ao-tools/ao-edit-telem/ao-edit-telem.c b/ao-tools/ao-edit-telem/ao-edit-telem.c new file mode 100644 index 00000000..3f6830e7 --- /dev/null +++ b/ao-tools/ao-edit-telem/ao-edit-telem.c @@ -0,0 +1,192 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#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 ] [--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); + +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; + char *s; + FILE *file; + int serial; + 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; + } + s = strstr(argv[i], "-serial-"); + if (s) + serial = atoi(s + 8); + else + serial = 0; + 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; +} diff --git a/configure.ac b/configure.ac index 9e5dcaa7..f9a892df 100644 --- a/configure.ac +++ b/configure.ac @@ -182,6 +182,7 @@ ao-tools/ao-stmload/Makefile ao-tools/ao-send-telem/Makefile ao-tools/ao-sky-flash/Makefile ao-tools/ao-dumpflash/Makefile +ao-tools/ao-edit-telem/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From 548cf57d5a5ea323bbfc3605b44c23fc48dec96b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Mar 2013 22:12:48 -0700 Subject: ao-tools: add ao-dump-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dumps out a µP log. Useful for µPusb bring-up Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/ao-dump-up/Makefile.am | 12 +++ ao-tools/ao-dump-up/ao-dump-up.1 | 45 +++++++++ ao-tools/ao-dump-up/ao-dump-up.c | 207 +++++++++++++++++++++++++++++++++++++++ configure.ac | 1 + 5 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 ao-tools/ao-dump-up/Makefile.am create mode 100644 ao-tools/ao-dump-up/ao-dump-up.1 create mode 100644 ao-tools/ao-dump-up/ao-dump-up.c (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index e4df2e63..4600f1d6 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,3 +1,3 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ - ao-dumpflash ao-edit-telem + ao-dumpflash ao-edit-telem ao-dump-up diff --git a/ao-tools/ao-dump-up/Makefile.am b/ao-tools/ao-dump-up/Makefile.am new file mode 100644 index 00000000..94bb94a9 --- /dev/null +++ b/ao-tools/ao-dump-up/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-dump-up + +AM_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 diff --git a/ao-tools/ao-dump-up/ao-dump-up.1 b/ao-tools/ao-dump-up/ao-dump-up.1 new file mode 100644 index 00000000..cfa81b46 --- /dev/null +++ b/ao-tools/ao-dump-up/ao-dump-up.1 @@ -0,0 +1,45 @@ +.\" +.\" Copyright © 2009 Keith Packard +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; 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] +.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. +.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 diff --git a/ao-tools/ao-dump-up/ao-dump-up.c b/ao-tools/ao-dump-up/ao-dump-up.c new file mode 100644 index 00000000..6268dc8b --- /dev/null +++ b/ao-tools/ao-dump-up/ao-dump-up.c @@ -0,0 +1,207 @@ +/* + * Copyright © 2009 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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 +#include +#include +#include +#include +#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' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--tty ] [--device ]\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 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 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); + 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, 0) == 'M' && get_nonwhite(cc, 1000) == 'P') + return 1; + } +} + +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]; + int nsamples; + int i; + int crc; + int current_crc; + + while ((c = getopt_long(argc, argv, "T:D:", options, NULL)) != -1) { + switch (c) { + case 'T': + tty = optarg; + break; + case 'D': + device = optarg; + break; + default: + usage(argv[0]); + break; + } + } + if (!tty) + tty = cc_usbdevs_find_by_arg(device, "FT230X Basic UART"); + 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) + printf("CRC valid\n"); + else + printf("CRC invalid\n"); + cc_usb_close(cc); + exit (0); +} diff --git a/configure.ac b/configure.ac index 977678f3..f54a8b4c 100644 --- a/configure.ac +++ b/configure.ac @@ -223,6 +223,7 @@ ao-tools/ao-send-telem/Makefile ao-tools/ao-sky-flash/Makefile ao-tools/ao-dumpflash/Makefile ao-tools/ao-edit-telem/Makefile +ao-tools/ao-dump-up/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From 15bc83a0eaaa9a43d67fdc3e9f412d5b2c1f06dd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Mar 2013 23:22:37 -0700 Subject: ao-tools: Make library support µPusb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set baud rate to 9600, look for FTDI-style names Signed-off-by: Keith Packard --- ao-tools/lib/cc-usb.c | 12 ++++++++++-- ao-tools/lib/cc-usb.h | 3 +++ ao-tools/lib/cc-usbdev.c | 25 +++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index 9f07e662..f8275243 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -254,10 +254,10 @@ cc_usb_printf(struct cc_usb *cc, char *format, ...) } int -cc_usb_getchar(struct cc_usb *cc) +cc_usb_getchar_timeout(struct cc_usb *cc, int timeout) { while (cc->in_pos == cc->in_count) { - if (_cc_usb_sync(cc, 5000) < 0) { + if (_cc_usb_sync(cc, timeout) < 0) { fprintf(stderr, "USB link timeout\n"); exit(1); } @@ -265,6 +265,12 @@ cc_usb_getchar(struct cc_usb *cc) return cc->in_buf[cc->in_pos++]; } +int +cc_usb_getchar(struct cc_usb *cc) +{ + return cc_usb_getchar_timeout(cc, 5000); +} + void cc_usb_getline(struct cc_usb *cc, char *line, int max) { @@ -420,6 +426,8 @@ cc_usb_open(char *tty) tcgetattr(cc->fd, &termios); save_termios = termios; cfmakeraw(&termios); + cfsetospeed(&termios, B9600); + cfsetispeed(&termios, B9600); tcsetattr(cc->fd, TCSAFLUSH, &termios); cc_usb_printf(cc, "\nE 0\nm 0\n"); do { diff --git a/ao-tools/lib/cc-usb.h b/ao-tools/lib/cc-usb.h index e90e1195..f1193456 100644 --- a/ao-tools/lib/cc-usb.h +++ b/ao-tools/lib/cc-usb.h @@ -53,6 +53,9 @@ cc_usb_sync(struct cc_usb *cc); void cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len); +int +cc_usb_getchar_timeout(struct cc_usb *cc, int timeout); + int cc_usb_getchar(struct cc_usb *cc); diff --git a/ao-tools/lib/cc-usbdev.c b/ao-tools/lib/cc-usbdev.c index a19e231c..95bfa244 100644 --- a/ao-tools/lib/cc-usbdev.c +++ b/ao-tools/lib/cc-usbdev.c @@ -132,11 +132,23 @@ usb_tty(char *sys) /* Check for tty/ttyACMx style names */ tty_dir = cc_fullname(endpoint_full, "tty"); - free(endpoint_full); ntty = scandir(tty_dir, &namelist, dir_filter_tty, alphasort); free (tty_dir); + if (ntty > 0) { + tty = cc_fullname("/dev", namelist[0]->d_name); + free(endpoint_full); + free(namelist); + return tty; + } + + /* Check for ttyACMx style names + */ + ntty = scandir(endpoint_full, &namelist, + dir_filter_tty, + alphasort); + free(endpoint_full); if (ntty > 0) { tty = cc_fullname("/dev", namelist[0]->d_name); free(namelist); @@ -197,6 +209,15 @@ dir_filter_dev(const struct dirent *d) return 1; } +static int +is_am(int idVendor, int idProduct) { + if (idVendor == 0xfffe) + return 1; + if (idVendor == 0x0403 && idProduct == 0x6015) + return 1; + return 0; +} + struct cc_usbdevs * cc_usbdevs_scan(void) { @@ -220,7 +241,7 @@ cc_usbdevs_scan(void) dir = cc_fullname(USB_DEVICES, ents[e]->d_name); dev = usb_scan_device(dir); free(dir); - if (dev->idVendor == 0xfffe && dev->tty) { + if (is_am(dev->idVendor, dev->idProduct) && dev->tty) { if (devs->dev) devs->dev = realloc(devs->dev, (devs->ndev + 1) * sizeof (struct usbdev *)); -- cgit v1.2.3 From 649999863c7228ead0225968752d068dc0d30091 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 30 Mar 2013 01:33:49 -0700 Subject: altos: Add logging and telem to telegps This turns on telemetry, APRS, RDF and data logging for telegps. Data is logged as soon as GPS has a date to create the right filename, using files of the form YYYYMMDD.LOG which just barely fits in a FAT filename. Telemetry/RDF/APRS are all separately controllable. Signed-off-by: Keith Packard --- ao-tools/ao-telem/ao-telem.c | 9 ++++-- src/core/ao_gps_report_mega.c | 1 + src/core/ao_telemetry.c | 3 ++ src/drivers/ao_log_fat.c | 74 +++++++++++++++++++++++++++++++++++++++++++ src/telegps-v0.1/Makefile | 5 ++- src/telegps-v0.1/ao_telegps.c | 9 +++++- 6 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 src/drivers/ao_log_fat.c (limited to 'ao-tools') diff --git a/ao-tools/ao-telem/ao-telem.c b/ao-tools/ao-telem/ao-telem.c index e7fc8e26..d2dae5a7 100644 --- a/ao-tools/ao-telem/ao-telem.c +++ b/ao-tools/ao-telem/ao-telem.c @@ -24,6 +24,7 @@ #include "cc.h" static const struct option options[] = { + { .name = "crc", .has_arg = 0, .val = 'c' }, { 0, 0, 0, 0}, }; @@ -44,8 +45,12 @@ main (int argc, char **argv) char *s; FILE *file; int serial; - while ((c = getopt_long(argc, argv, "", options, NULL)) != -1) { + int ignore_crc = 0; + while ((c = getopt_long(argc, argv, "c", options, NULL)) != -1) { switch (c) { + case 'c': + ignore_crc = 1; + break; default: usage(argv[0]); break; @@ -74,7 +79,7 @@ main (int argc, char **argv) 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 ((telem.generic.status & (1 << 7)) == 0) { + if (!ignore_crc && (telem.generic.status & (1 << 7)) == 0) { printf ("CRC error\n"); continue; } diff --git a/src/core/ao_gps_report_mega.c b/src/core/ao_gps_report_mega.c index 47891cab..e3af4307 100644 --- a/src/core/ao_gps_report_mega.c +++ b/src/core/ao_gps_report_mega.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_log.h" void ao_gps_report_mega(void) diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 8d440e15..3aa315c7 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_log.h" #include "ao_product.h" static __pdata uint16_t ao_telemetry_interval; @@ -306,12 +307,14 @@ ao_telemetry(void) #ifdef AO_SEND_ALL_BARO ao_send_baro(); #endif +#if HAS_FLIGHT #ifdef AO_SEND_MEGA ao_send_mega_sensor(); ao_send_mega_data(); #else ao_send_sensor(); #endif +#endif #if HAS_COMPANION if (ao_companion_running) diff --git a/src/drivers/ao_log_fat.c b/src/drivers/ao_log_fat.c new file mode 100644 index 00000000..684148b7 --- /dev/null +++ b/src/drivers/ao_log_fat.c @@ -0,0 +1,74 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" +#include "ao_log.h" +#include "ao_fat.h" + +static uint8_t log_year, log_month, log_day; +static uint8_t log_running; +static uint8_t log_mutex; + +static void +ao_log_open(void) +{ + char name[12]; + + sprintf(name,"%04d%02d%02dLOG", 2000 + log_year, log_month, log_day); + if (ao_fat_open(name, AO_FAT_OPEN_WRITE) == AO_FAT_SUCCESS) + log_running = 1; +} + +static void +ao_log_close(void) +{ + log_running = 0; + ao_fat_close(); +} + +uint8_t +ao_log_full(void) +{ + return ao_fat_full(); +} + +uint8_t +ao_log_mega(struct ao_log_mega *log) +{ + uint8_t wrote = 0; + ao_mutex_get(&log_mutex); + if (log->type == AO_LOG_GPS_TIME) { + if (log_running && + (log_year != log->u.gps.year || + log_month != log->u.gps.month || + log_day != log->u.gps.day)) { + ao_log_close(); + } + if (!log_running) { + log_year = log->u.gps.year; + log_month = log->u.gps.month; + log_day = log->u.gps.day; + ao_log_open(); + } + } + if (log_running) { + wrote = ao_fat_write(log, sizeof (*log)) == AO_FAT_SUCCESS; + ao_fat_sync(); + } + ao_mutex_put(&log_mutex); + return wrote; +} diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index ae36c9fd..8e610db7 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -55,7 +55,10 @@ ALTOS_SRC = \ ao_eeprom_stm.c \ ao_sdcard.c \ ao_bufio.c \ - ao_fat.c + ao_fat.c \ + ao_log_fat.c \ + ao_gps_report_mega.c \ + ao_telemetry.c PRODUCT=TeleGPS-v0.1 PRODUCT_DEF=-DTELEGPS diff --git a/src/telegps-v0.1/ao_telegps.c b/src/telegps-v0.1/ao_telegps.c index 2f1f38f2..91796c21 100644 --- a/src/telegps-v0.1/ao_telegps.c +++ b/src/telegps-v0.1/ao_telegps.c @@ -19,6 +19,8 @@ #include #include +uint16_t ao_flight_number = 1; + int main(void) { @@ -47,9 +49,14 @@ main(void) ao_usb_init(); ao_radio_init(); + ao_fat_init(); + ao_gps_init(); + ao_gps_report_mega_init(); - ao_fat_init(); + ao_telemetry_init(); + ao_telemetry_set_interval(AO_SEC_TO_TICKS(1)); + ao_rdf_set(1); ao_config_init(); -- cgit v1.2.3 From db01557ce493c435db177fda78653697ba2afa51 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 23 Mar 2013 02:10:38 -0700 Subject: ao-tools/ao-stmload: Be smarter about ELF parsing. Retry open on failure. Figuring out what goes where is tricky; turns out we want to pull all of the sections that map inside any program area that is supposed to be loaded from the file. So, we walk the program headers, then walk all of the section headers looking for those that suck data from the same portion of the file. Compute where in ROM each relevant section goes and build a full ROM image in memory using that. This patch also adds code to close and re-open the device if the first open failed to do what we want. Much nicer to have the computer figure out when the open succeeded rather than having people re-run the app. Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 114 +++++++++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 16 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index a471dcc4..89b818da 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -69,6 +69,11 @@ find_symbols (Elf *e) int i, symbol_count, s; int required = 0; char *symbol_name; + char *section_name; + size_t shstrndx; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return 0; /* * Find the symbols @@ -76,9 +81,29 @@ find_symbols (Elf *e) scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) return 0; +#if 0 + section_name = elf_strptr(e, shstrndx, shdr.sh_name); + + printf ("name %s\n", section_name); + + if (shdr.sh_type == SHT_PROGBITS) + { + printf ("\ttype %lx\n", shdr.sh_type); + printf ("\tflags %lx\n", shdr.sh_flags); + printf ("\taddr %lx\n", shdr.sh_addr); + printf ("\toffset %lx\n", shdr.sh_offset); + printf ("\tsize %lx\n", shdr.sh_size); + printf ("\tlink %lx\n", shdr.sh_link); + printf ("\tinfo %lx\n", shdr.sh_info); + printf ("\taddralign %lx\n", shdr.sh_addralign); + printf ("\tentsize %lx\n", shdr.sh_entsize); + } +#endif + if (shdr.sh_type == SHT_SYMTAB) { symbol_data = elf_getdata(scn, NULL); symbol_count = shdr.sh_size / shdr.sh_entsize; @@ -199,9 +224,15 @@ get_load(Elf *e) uint8_t *buf; char *got_name; size_t nphdr; - int p; + size_t p; GElf_Phdr phdr; + GElf_Addr p_paddr; + GElf_Off p_offset; + GElf_Addr sh_paddr; struct load *load = NULL; + char *section_name; + size_t nshdr; + size_t s; if (elf_getshdrstrndx(e, &shstrndx) < 0) return 0; @@ -209,6 +240,9 @@ get_load(Elf *e) if (elf_getphdrnum(e, &nphdr) < 0) return 0; + if (elf_getshdrnum(e, &nshdr) < 0) + return 0; + /* * As far as I can tell, all of the phdr sections should * be flashed to memory @@ -218,16 +252,54 @@ get_load(Elf *e) /* Find this phdr */ gelf_getphdr(e, p, &phdr); + if (phdr.p_type != PT_LOAD) + continue; + + p_offset = phdr.p_offset; /* Get the associated file section */ - scn = gelf_offscn(e, phdr.p_offset); - if (gelf_getshdr(scn, &shdr) != &shdr) - abort(); +#if 0 + printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", + (uint32_t) phdr.p_offset, + (uint32_t) phdr.p_vaddr, + (uint32_t) phdr.p_paddr, + (uint32_t) phdr.p_filesz, + (uint32_t) phdr.p_memsz); +#endif + + for (s = 0; s < nshdr; s++) { + scn = elf_getscn(e, s); + + if (!scn) { + printf ("getscn failed\n"); + abort(); + } + if (gelf_getshdr(scn, &shdr) != &shdr) { + printf ("gelf_getshdr failed\n"); + abort(); + } - data = elf_getdata(scn, NULL); + section_name = elf_strptr(e, shstrndx, shdr.sh_name); - /* Write the section data into the memory block */ - load = load_write(load, phdr.p_paddr, phdr.p_filesz, data->d_buf); + if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { + + if (shdr.sh_size == 0) + continue; + + sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; + + printf ("\tsize %08x rom %08x exec %08x %s\n", + (uint32_t) shdr.sh_size, + (uint32_t) sh_paddr, + (uint32_t) shdr.sh_addr, + section_name); + + data = elf_getdata(scn, NULL); + + /* Write the section data into the memory block */ + load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); + } + } } return load; } @@ -422,6 +494,7 @@ main (int argc, char **argv) stlink_t *sl; int was_flashed = 0; struct load *load; + int tries; while ((c = getopt_long(argc, argv, "D:c:s:", options, NULL)) != -1) { switch (c) { @@ -472,19 +545,28 @@ main (int argc, char **argv) /* Connect to the programming dongle */ - if (device) { - sl = stlink_v1_open(50); - } else { - sl = stlink_open_usb(50); + for (tries = 0; tries < 3; tries++) { + if (device) { + 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); } - if (!sl) { - fprintf (stderr, "No STLink devices present\n"); - done (sl, 1); + if (sl->chip_id == 0) { + fprintf (stderr, "Debugger connection failed\n"); + done(sl, 1); } - sl->verbose = 50; - /* Verify that the loaded image fits entirely within device flash */ if (load->addr < sl->flash_base || -- cgit v1.2.3 From 0b6128d634c49e1790675ae8111e970b1af1f141 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Mar 2013 15:29:32 -0700 Subject: ao-tools/lib: Deal with binary USB data in debugging output Dump non-ascii characters in hex format. Signed-off-by: Keith Packard --- ao-tools/lib/cc-usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'ao-tools') diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index f8275243..485583f9 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -140,7 +140,10 @@ cc_usb_dbg(int indent, uint8_t *bytes, int len) case '\n': eol = 1; default: - ccdbg_debug(CC_DEBUG_BITBANG, "%c", c); + if (c < ' ' || c > '~') + ccdbg_debug(CC_DEBUG_BITBANG, "\\%02x", c); + else + ccdbg_debug(CC_DEBUG_BITBANG, "%c", c); } } } @@ -190,6 +193,7 @@ _cc_usb_sync(struct cc_usb *cc, int wait_for_input) ret = read(cc->fd, cc->in_buf + cc->in_count, CC_IN_BUF - cc->in_count); if (ret > 0) { + int i; cc_usb_dbg(24, cc->in_buf + cc->in_count, ret); cc->in_count += ret; if (cc->hex_count) -- cgit v1.2.3 From 1f30b1f14dbab6e6ea94177e459c80732e31e433 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Mar 2013 15:30:24 -0700 Subject: ao-tools/lib: Add loading support for 32-bit ihx files These place the upper 16 bits of the address in a special record. That requires handling records in file order, so don't sort them in address order anymore, instead find the bounds of the loaded data by scanning them all. Signed-off-by: Keith Packard --- ao-tools/lib/ccdbg-hex.c | 95 +++++++++++++++++++++++++++++++++++++----------- ao-tools/lib/ccdbg.h | 7 +++- 2 files changed, 78 insertions(+), 24 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/lib/ccdbg-hex.c b/ao-tools/lib/ccdbg-hex.c index dfea9156..184b4e3b 100644 --- a/ao-tools/lib/ccdbg-hex.c +++ b/ao-tools/lib/ccdbg-hex.c @@ -233,15 +233,6 @@ ccdbg_hex_file_free(struct hex_file *hex) free(hex); } -static int -ccdbg_hex_record_compar(const void *av, const void *bv) -{ - const struct hex_record *a = *(struct hex_record **) av; - const struct hex_record *b = *(struct hex_record **) bv; - - return (int) a->address - (int) b->address; -} - struct hex_file * ccdbg_hex_file_read(FILE *file, char *name) { @@ -272,11 +263,6 @@ ccdbg_hex_file_read(FILE *file, char *name) if (record->type == HEX_RECORD_EOF) done = 1; } - /* - * Sort them into increasing addresses, except for EOF - */ - qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *), - ccdbg_hex_record_compar); return hex; bail: @@ -288,16 +274,45 @@ struct hex_image * ccdbg_hex_image_create(struct hex_file *hex) { struct hex_image *image; - struct hex_record *first, *last, *record; + struct hex_record *record; int i; + uint32_t addr; uint32_t base, bound; uint32_t offset; + uint32_t extended_addr; + int length; - first = hex->records[0]; - last = hex->records[hex->nrecord - 2]; /* skip EOF */ - base = (uint32_t) first->address; - bound = (uint32_t) last->address + (uint32_t) last->length; + base = 0xffffffff; + bound = 0x0; + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + uint32_t r_bound; + record = hex->records[i]; + switch (record->type) { + case 0: + addr = extended_addr + record->address; + r_bound = addr + record->length; + if (addr < base) + base = addr; + if (r_bound > bound) + bound = r_bound; + break; + case 1: + break; + case 2: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } + + } length = bound - base; image = calloc(sizeof(struct hex_image) + length, 1); if (!image) @@ -305,10 +320,24 @@ ccdbg_hex_image_create(struct hex_file *hex) image->address = base; image->length = length; memset(image->data, 0xff, length); - for (i = 0; i < hex->nrecord - 1; i++) { + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { record = hex->records[i]; - offset = record->address - base; - memcpy(image->data + offset, record->data, record->length); + switch (record->type) { + case 0: + addr = extended_addr + record->address; + offset = addr - base; + memcpy(image->data + offset, record->data, record->length); + break; + case 1: + break; + case 2: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } } return image; } @@ -328,3 +357,25 @@ ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b) return 0; return 1; } + +struct hex_image * +ccdbg_hex_load(char *filename) +{ + FILE *file; + struct hex_file *hex_file; + struct hex_image *hex_image; + + file = fopen (filename, "r"); + if (!file) + return 0; + + hex_file = ccdbg_hex_file_read(file, filename); + fclose(file); + if (!hex_file) + return 0; + hex_image = ccdbg_hex_image_create(hex_file); + if (!hex_image) + return 0; + ccdbg_hex_file_free(hex_file); + return hex_image; +} diff --git a/ao-tools/lib/ccdbg.h b/ao-tools/lib/ccdbg.h index ca596143..a27ff5d1 100644 --- a/ao-tools/lib/ccdbg.h +++ b/ao-tools/lib/ccdbg.h @@ -122,8 +122,8 @@ struct hex_file { }; struct hex_image { - uint16_t address; - uint16_t length; + uint32_t address; + uint32_t length; uint8_t data[0]; }; @@ -253,6 +253,9 @@ ccdbg_hex_image_create(struct hex_file *hex); void ccdbg_hex_image_free(struct hex_image *image); +struct hex_image * +ccdbg_hex_load(char *filename); + int ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b); -- cgit v1.2.3 From c9ba2d17b979410acfa41f9954674757f7f321fc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Mar 2013 15:33:31 -0700 Subject: ao-tools/ao-stmload: Fix ELF, add IHX, add self-flashing This splits loading into ELF and IHX paths, and splits flashing into stlink and self-flashing paths. Signed-off-by: Keith Packard --- ao-tools/ao-stmload/Makefile.am | 9 +- ao-tools/ao-stmload/ao-elf.c | 303 ++++++++++++++++++ ao-tools/ao-stmload/ao-elf.h | 24 ++ ao-tools/ao-stmload/ao-selfload.c | 118 +++++++ ao-tools/ao-stmload/ao-stmload.c | 653 +++++++++++++++----------------------- ao-tools/ao-stmload/ao-stmload.h | 45 +++ 6 files changed, 750 insertions(+), 402 deletions(-) create mode 100644 ao-tools/ao-stmload/ao-elf.c create mode 100644 ao-tools/ao-stmload/ao-elf.h create mode 100644 ao-tools/ao-stmload/ao-selfload.c create mode 100644 ao-tools/ao-stmload/ao-stmload.h (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/Makefile.am b/ao-tools/ao-stmload/Makefile.am index 5aea7db4..4eaf699c 100644 --- a/ao-tools/ao-stmload/Makefile.am +++ b/ao-tools/ao-stmload/Makefile.am @@ -4,11 +4,14 @@ bin_PROGRAMS=ao-stmload LIBSTLINKDIR=/local/src/stlink -AM_CFLAGS=$(LIBSTLINK_CFLAGS) $(LIBUSB_CFLAGS) -I../lib +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBSTLINK_CFLAGS) $(LIBUSB_CFLAGS) +AO_STMLOAD_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a -ao_stmload_LDADD=$(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf +ao_stmload_DEPENDENCIES = $(AO_STMLOAD_LIBS) -ao_stmload_SOURCES=ao-stmload.c +ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf + +ao_stmload_SOURCES=ao-stmload.c ao-elf.c ao-stmload.h ao-selfload.c man_MANS = ao-stmload.1 diff --git a/ao-tools/ao-stmload/ao-elf.c b/ao-tools/ao-stmload/ao-elf.c new file mode 100644 index 00000000..dad8fb80 --- /dev/null +++ b/ao-tools/ao-stmload/ao-elf.c @@ -0,0 +1,303 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao-elf.h" +#include +#include +#include +#include +#include +#include +#include +#include "ccdbg.h" +#include "ao-stmload.h" + +/* + * Look through the Elf file for the AltOS symbols + * that can be adjusted before the image is written + * to the device + */ +static int +find_symbols (Elf *e) +{ + Elf_Scn *scn; + Elf_Data *symbol_data = NULL; + GElf_Shdr shdr; + GElf_Sym sym; + int i, symbol_count, s; + int required = 0; + char *symbol_name; + char *section_name; + size_t shstrndx; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return 0; + + /* + * Find the symbols + */ + + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + + if (gelf_getshdr(scn, &shdr) != &shdr) + return 0; + + if (shdr.sh_type == SHT_SYMTAB) { + symbol_data = elf_getdata(scn, NULL); + symbol_count = shdr.sh_size / shdr.sh_entsize; + break; + } + } + + if (!symbol_data) + return 0; + + for (i = 0; i < symbol_count; i++) { + gelf_getsym(symbol_data, i, &sym); + + symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name); + + for (s = 0; s < ao_num_symbols; s++) + if (!strcmp (ao_symbols[s].name, symbol_name)) { + int t; + ao_symbols[s].addr = sym.st_value; + if (ao_symbols[s].required) + ++required; + } + } + + return required >= ao_num_required_symbols; +} + +uint32_t round4(uint32_t a) { + return (a + 3) & ~3; +} + +struct hex_image * +new_load (uint32_t addr, uint32_t len) +{ + struct hex_image *new; + + len = round4(len); + new = calloc (1, sizeof (struct hex_image) + len); + if (!new) + abort(); + + new->address = addr; + new->length = len; + return new; +} + +void +load_paste(struct hex_image *into, struct hex_image *from) +{ + if (from->address < into->address || into->address + into->length < from->address + from->length) + abort(); + + memcpy(into->data + from->address - into->address, from->data, from->length); +} + +/* + * Make a new load structure large enough to hold the old one and + * the new data + */ +struct hex_image * +expand_load(struct hex_image *from, uint32_t address, uint32_t length) +{ + struct hex_image *new; + + if (from) { + uint32_t from_last = from->address + from->length; + uint32_t last = address + length; + + if (address > from->address) + address = from->address; + if (last < from_last) + last = from_last; + + length = last - address; + + if (address == from->address && length == from->length) + return from; + } + new = new_load(address, length); + if (from) { + load_paste(new, from); + free (from); + } + return new; +} + +/* + * Create a new load structure with data from the existing one + * and the new data + */ +struct hex_image * +load_write(struct hex_image *from, uint32_t address, uint32_t length, void *data) +{ + struct hex_image *new; + + new = expand_load(from, address, length); + memcpy(new->data + address - new->address, data, length); + return new; +} + +/* + * Construct a large in-memory block for all + * of the loaded sections of the program + */ +static struct hex_image * +get_load(Elf *e) +{ + Elf_Scn *scn; + size_t shstrndx; + GElf_Shdr shdr; + Elf_Data *data; + char *got_name; + size_t nphdr; + size_t p; + GElf_Phdr phdr; + GElf_Addr p_paddr; + GElf_Off p_offset; + GElf_Addr sh_paddr; + struct hex_image *load = NULL; + char *section_name; + size_t nshdr; + size_t s; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return 0; + + if (elf_getphdrnum(e, &nphdr) < 0) + return 0; + + if (elf_getshdrnum(e, &nshdr) < 0) + return 0; + + /* + * As far as I can tell, all of the phdr sections should + * be flashed to memory + */ + for (p = 0; p < nphdr; p++) { + + /* Find this phdr */ + gelf_getphdr(e, p, &phdr); + + if (phdr.p_type != PT_LOAD) + continue; + + p_offset = phdr.p_offset; + /* Get the associated file section */ + +#if 0 + printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", + (uint32_t) phdr.p_offset, + (uint32_t) phdr.p_vaddr, + (uint32_t) phdr.p_paddr, + (uint32_t) phdr.p_filesz, + (uint32_t) phdr.p_memsz); +#endif + + for (s = 0; s < nshdr; s++) { + scn = elf_getscn(e, s); + + if (!scn) { + printf ("getscn failed\n"); + abort(); + } + if (gelf_getshdr(scn, &shdr) != &shdr) { + printf ("gelf_getshdr failed\n"); + abort(); + } + + section_name = elf_strptr(e, shstrndx, shdr.sh_name); + + if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { + + if (shdr.sh_size == 0) + continue; + + sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; + + printf ("\tsize %08x rom %08x exec %08x %s\n", + (uint32_t) shdr.sh_size, + (uint32_t) sh_paddr, + (uint32_t) shdr.sh_addr, + section_name); + + data = elf_getdata(scn, NULL); + + /* Write the section data into the memory block */ + load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); + } + } + } + return load; +} + +/* + * Open the specified ELF file and + * check for the symbols we need + */ + +struct hex_image * +ao_load_elf(char *name) +{ + int fd; + Elf *e; + Elf_Scn *scn; + Elf_Data *symbol_data = NULL; + GElf_Shdr shdr; + GElf_Sym sym; + size_t n, shstrndx, sz; + int i, symbol_count, s; + int required = 0; + struct hex_image *image; + + if (elf_version(EV_CURRENT) == EV_NONE) + return NULL; + + fd = open(name, O_RDONLY, 0); + + if (fd < 0) + return NULL; + + e = elf_begin(fd, ELF_C_READ, NULL); + + if (!e) + return NULL; + + if (elf_kind(e) != ELF_K_ELF) + return NULL; + + if (elf_getshdrstrndx(e, &shstrndx) != 0) + return NULL; + + if (!find_symbols(e)) { + fprintf (stderr, "Cannot find required symbols\n"); + return NULL; + } + + image = get_load(e); + if (!image) { + fprintf (stderr, "Cannot create memory image from file\n"); + return NULL; + } + + return image; +} diff --git a/ao-tools/ao-stmload/ao-elf.h b/ao-tools/ao-stmload/ao-elf.h new file mode 100644 index 00000000..4303d5ca --- /dev/null +++ b/ao-tools/ao-stmload/ao-elf.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_ELF_H_ +#define _AO_ELF_H_ + +struct hex_image * +ao_load_elf(char *name); + +#endif diff --git a/ao-tools/ao-stmload/ao-selfload.c b/ao-tools/ao-stmload/ao-selfload.c new file mode 100644 index 00000000..b3105b21 --- /dev/null +++ b/ao-tools/ao-stmload/ao-selfload.c @@ -0,0 +1,118 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#include +#include "cc.h" +#include "cc-usb.h" +#include "ccdbg.h" +#include "ao-stmload.h" + +void +ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ + int byte; + cc_usb_sync(cc); + cc_usb_printf(cc, "R %x\n", address); +// printf ("read %08x\n", address); + for (byte = 0; byte < 0x100; byte++) { + block[byte] = cc_usb_getchar(cc); +// printf (" %02x", block[byte]); +// if ((byte & 0xf) == 0xf) +// printf ("\n"); + } +} + +void +ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ + int byte; + cc_usb_sync(cc); + cc_usb_printf(cc, "W %x\n", address); +// printf ("write %08x\n", address); + for (byte = 0; byte < 0x100; byte++) { + cc_usb_printf(cc, "%c", block[byte]); +// printf (" %02x", block[byte]); +// if ((byte & 0xf) == 0xf) +// printf ("\n"); + } +} + +struct hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) +{ + struct hex_image *image; + int pages; + int page; + uint32_t base = address & ~0xff; + uint32_t bound = (address + length + 0xff) & ~0xff; + + image = calloc(sizeof (struct hex_image) + (bound - base), 1); + image->address = base; + image->length = bound - base; + pages = image->length / 0x100; + for (page = 0; page < pages; page++) + ao_self_block_read(cc, image->address + page * 0x100, image->data + page * 0x100); + return image; +} + +int +ao_self_write(struct cc_usb *cc, struct hex_image *image) +{ + uint8_t block[256]; + uint8_t check[256]; + uint32_t base, bound, length, address; + uint32_t pages; + uint32_t page; + + base = image->address & ~0xff; + bound = (image->address + image->length + 0xff) & ~0xff; + + address = base; + length = bound - base; + + pages = length / 0x100; + printf ("Write %08x %d pages: ", address, length/0x100); fflush(stdout); + for (page = 0; page < pages; page++) { + uint32_t start, stop; + address = base + page * 0x100; + + if (address < image->address || address + 0x100 > image->address + image->length) { + ao_self_block_read(cc, address, block); + } + start = address; + stop = address + 0x100; + if (start < image->address) + start = image->address; + if (stop > image->address + image->length) + stop = image->address + image->length; + memcpy(block + start - address, image->data + start - image->address, stop - start); + ao_self_block_write(cc, address, block); + ao_self_block_read(cc, address, check); + if (memcmp(block, check, 0x100) != 0) { + fprintf(stderr, "Block at 0x%08x doesn't match\n", address); + return 0; + } + putchar('.'); fflush(stdout); + } + printf("done\n"); + return 1; +} diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 89b818da..b9bf4392 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -26,365 +26,107 @@ #include #include #include "stlink-common.h" +#include "ao-elf.h" +#include "ccdbg.h" +#include "cc-usb.h" +#include "cc.h" +#include "ao-stmload.h" #define AO_USB_DESC_STRING 3 -struct sym { - unsigned addr; - char *name; - int required; -} ao_symbols[] = { +struct sym ao_symbols[] = { - { 0, "ao_romconfig_version", 1 }, + { 0, 0x08002100, "ao_romconfig_version", 1 }, #define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) - { 0, "ao_romconfig_check", 1 }, + { 0, 0x08002102, "ao_romconfig_check", 1 }, #define AO_ROMCONFIG_CHECK (ao_symbols[1].addr) - { 0, "ao_serial_number", 1 }, + { 0, 0x08002104, "ao_serial_number", 1 }, #define AO_SERIAL_NUMBER (ao_symbols[2].addr) - { 0, "ao_usb_descriptors", 0 }, -#define AO_USB_DESCRIPTORS (ao_symbols[3].addr) + { 0, 0x08002108, "ao_radio_cal", 0 }, +#define AO_RADIO_CAL (ao_symbols[3].addr) - { 0, "ao_radio_cal", 0 }, -#define AO_RADIO_CAL (ao_symbols[4].addr) + { 0, 0x0800210c, "ao_usb_descriptors", 0 }, +#define AO_USB_DESCRIPTORS (ao_symbols[4].addr) }; #define NUM_SYMBOLS 5 #define NUM_REQUIRED_SYMBOLS 3 -/* - * Look through the Elf file for the AltOS symbols - * that can be adjusted before the image is written - * to the device - */ -static int -find_symbols (Elf *e) -{ - Elf_Scn *scn; - Elf_Data *symbol_data = NULL; - GElf_Shdr shdr; - GElf_Sym sym; - int i, symbol_count, s; - int required = 0; - char *symbol_name; - char *section_name; - size_t shstrndx; - - if (elf_getshdrstrndx(e, &shstrndx) < 0) - return 0; - - /* - * Find the symbols - */ - - scn = NULL; - while ((scn = elf_nextscn(e, scn)) != NULL) { - - if (gelf_getshdr(scn, &shdr) != &shdr) - return 0; - -#if 0 - section_name = elf_strptr(e, shstrndx, shdr.sh_name); - - printf ("name %s\n", section_name); - - if (shdr.sh_type == SHT_PROGBITS) - { - printf ("\ttype %lx\n", shdr.sh_type); - printf ("\tflags %lx\n", shdr.sh_flags); - printf ("\taddr %lx\n", shdr.sh_addr); - printf ("\toffset %lx\n", shdr.sh_offset); - printf ("\tsize %lx\n", shdr.sh_size); - printf ("\tlink %lx\n", shdr.sh_link); - printf ("\tinfo %lx\n", shdr.sh_info); - printf ("\taddralign %lx\n", shdr.sh_addralign); - printf ("\tentsize %lx\n", shdr.sh_entsize); - } -#endif - - if (shdr.sh_type == SHT_SYMTAB) { - symbol_data = elf_getdata(scn, NULL); - symbol_count = shdr.sh_size / shdr.sh_entsize; - break; - } - } - - if (!symbol_data) - return 0; - - for (i = 0; i < symbol_count; i++) { - gelf_getsym(symbol_data, i, &sym); - - symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name); - - for (s = 0; s < NUM_SYMBOLS; s++) - if (!strcmp (ao_symbols[s].name, symbol_name)) { - int t; - ao_symbols[s].addr = sym.st_value; - if (ao_symbols[s].required) - ++required; - } - } - - return required >= NUM_REQUIRED_SYMBOLS; -} - -struct load { - uint32_t addr; - uint32_t len; - uint8_t buf[0]; -}; - -uint32_t round4(uint32_t a) { - return (a + 3) & ~3; -} - -struct load * -new_load (uint32_t addr, uint32_t len) -{ - struct load *new; - - len = round4(len); - new = calloc (1, sizeof (struct load) + len); - if (!new) - abort(); - - new->addr = addr; - new->len = len; - return new; -} - -void -load_paste(struct load *into, struct load *from) -{ - if (from->addr < into->addr || into->addr + into->len < from->addr + from->len) - abort(); - - memcpy(into->buf + from->addr - into->addr, from->buf, from->len); -} - -/* - * Make a new load structure large enough to hold the old one and - * the new data - */ -struct load * -expand_load(struct load *from, uint32_t addr, uint32_t len) -{ - struct load *new; - - if (from) { - uint32_t from_last = from->addr + from->len; - uint32_t last = addr + len; - - if (addr > from->addr) - addr = from->addr; - if (last < from_last) - last = from_last; - - len = last - addr; - - if (addr == from->addr && len == from->len) - return from; - } - new = new_load(addr, len); - if (from) { - load_paste(new, from); - free (from); - } - return new; -} - -/* - * Create a new load structure with data from the existing one - * and the new data - */ -struct load * -load_write(struct load *from, uint32_t addr, uint32_t len, void *data) -{ - struct load *new; - - new = expand_load(from, addr, len); - memcpy(new->buf + addr - new->addr, data, len); - return new; -} - -/* - * Construct a large in-memory block for all - * of the loaded sections of the program - */ -static struct load * -get_load(Elf *e) -{ - Elf_Scn *scn; - size_t shstrndx; - GElf_Shdr shdr; - Elf_Data *data; - uint8_t *buf; - char *got_name; - size_t nphdr; - size_t p; - GElf_Phdr phdr; - GElf_Addr p_paddr; - GElf_Off p_offset; - GElf_Addr sh_paddr; - struct load *load = NULL; - char *section_name; - size_t nshdr; - size_t s; - - if (elf_getshdrstrndx(e, &shstrndx) < 0) - return 0; - - if (elf_getphdrnum(e, &nphdr) < 0) - return 0; - - if (elf_getshdrnum(e, &nshdr) < 0) - return 0; - - /* - * As far as I can tell, all of the phdr sections should - * be flashed to memory - */ - for (p = 0; p < nphdr; p++) { - - /* Find this phdr */ - gelf_getphdr(e, p, &phdr); - - if (phdr.p_type != PT_LOAD) - continue; - - p_offset = phdr.p_offset; - /* Get the associated file section */ - -#if 0 - printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", - (uint32_t) phdr.p_offset, - (uint32_t) phdr.p_vaddr, - (uint32_t) phdr.p_paddr, - (uint32_t) phdr.p_filesz, - (uint32_t) phdr.p_memsz); -#endif - - for (s = 0; s < nshdr; s++) { - scn = elf_getscn(e, s); - - if (!scn) { - printf ("getscn failed\n"); - abort(); - } - if (gelf_getshdr(scn, &shdr) != &shdr) { - printf ("gelf_getshdr failed\n"); - abort(); - } - - section_name = elf_strptr(e, shstrndx, shdr.sh_name); - - if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { - - if (shdr.sh_size == 0) - continue; - - sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; - - printf ("\tsize %08x rom %08x exec %08x %s\n", - (uint32_t) shdr.sh_size, - (uint32_t) sh_paddr, - (uint32_t) shdr.sh_addr, - section_name); - - data = elf_getdata(scn, NULL); - - /* Write the section data into the memory block */ - load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); - } - } - } - return load; -} +int ao_num_symbols = NUM_SYMBOLS; +int ao_num_required_symbols = NUM_REQUIRED_SYMBOLS; /* * Edit the to-be-written memory block */ static int -rewrite(struct load *load, unsigned addr, uint8_t *data, int len) +rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length) { int i; - if (addr < load->addr || load->addr + load->len < addr + len) + if (address < load->address || load->address + load->length < address + length) return 0; - printf("rewrite %04x:", addr); - for (i = 0; i < len; i++) - printf (" %02x", load->buf[addr - load->addr + i]); + printf("rewrite %04x:", address); + for (i = 0; i < length; i++) + printf (" %02x", load->data[address - load->address + i]); printf(" ->"); - for (i = 0; i < len; i++) + for (i = 0; i < length; i++) printf (" %02x", data[i]); printf("\n"); - memcpy(load->buf + addr - load->addr, data, len); + memcpy(load->data + address - load->address, data, length); } /* - * Open the specified ELF file and - * check for the symbols we need + * Read a 16-bit value from the USB target */ -Elf * -ao_open_elf(char *name) +static uint16_t +get_uint16_cc(struct cc_usb *cc, uint32_t addr) { - int fd; - Elf *e; - Elf_Scn *scn; - Elf_Data *symbol_data = NULL; - GElf_Shdr shdr; - GElf_Sym sym; - size_t n, shstrndx, sz; - int i, symbol_count, s; - int required = 0; - - if (elf_version(EV_CURRENT) == EV_NONE) - return NULL; + struct hex_image *hex = ao_self_read(cc, addr, 2); + uint16_t v; + uint8_t *data; - fd = open(name, O_RDONLY, 0); - - if (fd < 0) - return NULL; - - e = elf_begin(fd, ELF_C_READ, NULL); - - if (!e) - return NULL; - - if (elf_kind(e) != ELF_K_ELF) - return NULL; - - if (elf_getshdrstrndx(e, &shstrndx) != 0) - return NULL; + if (!hex) + return 0; + data = hex->data + addr - hex->address; + v = data[0] | (data[1] << 8); + free(hex); + return v; +} - if (!find_symbols(e)) { - fprintf (stderr, "Cannot find required symbols\n"); - return NULL; - } +static uint32_t +get_uint32_cc(struct cc_usb *cc, uint32_t addr) +{ + struct hex_image *hex = ao_self_read(cc, addr, 4); + uint32_t v; + uint8_t *data; - return e; + if (!hex) + return 0; + data = hex->data + addr - hex->address; + v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + free(hex); + return v; } /* - * Read a 32-bit value from the target device with arbitrary + * Read a 16-bit value from the target device with arbitrary * alignment */ -static uint32_t -get_uint32(stlink_t *sl, uint32_t addr) +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; - uint32_t result; + uint16_t result; sl->q_len = 0; - printf ("read 0x%x\n", addr); actual_addr = addr & ~3; @@ -394,25 +136,37 @@ get_uint32(stlink_t *sl, uint32_t addr) abort(); off = addr & 3; - result = data[off] | (data[off + 1] << 8) | (data[off+2] << 16) | (data[off+3] << 24); - printf ("read 0x%08x = 0x%08x\n", addr, result); + result = data[off] | (data[off + 1] << 8); + return result; +} + +static uint16_t +get_uint16(stlink_t *sl, struct cc_usb *cc, uint32_t addr) +{ + uint16_t result; + if (cc) + result = get_uint16_cc(cc, addr); + else + result = get_uint16_sl(sl, addr); + printf ("read 0x%08x = 0x%04x\n", addr, result); return result; } /* - * Read a 16-bit value from the target device with arbitrary + * Read a 32-bit value from the target device with arbitrary * alignment */ -static uint16_t -get_uint16(stlink_t *sl, uint32_t addr) +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; - uint16_t result; + uint32_t result; sl->q_len = 0; + printf ("read 0x%x\n", addr); actual_addr = addr & ~3; @@ -422,8 +176,24 @@ get_uint16(stlink_t *sl, uint32_t addr) abort(); off = addr & 3; - result = data[off] | (data[off + 1] << 8); - printf ("read 0x%08x = 0x%04x\n", addr, result); + 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, struct cc_usb *cc, uint32_t addr) +{ + uint32_t result; + + if (cc) + result = get_uint32_cc(cc, addr); + else + result = get_uint32_sl(sl, addr); + printf ("read 0x%08x = 0x%08x\n", addr, result); return result; } @@ -436,10 +206,10 @@ get_uint16(stlink_t *sl, uint32_t addr) * places this at 0x100 from the start of the rom section */ static int -check_flashed(stlink_t *sl) +check_flashed(stlink_t *sl, struct cc_usb *cc) { - uint16_t romconfig_version = get_uint16(sl, AO_ROMCONFIG_VERSION); - uint16_t romconfig_check = get_uint16(sl, AO_ROMCONFIG_CHECK); + uint16_t romconfig_version = get_uint16(sl, cc, AO_ROMCONFIG_VERSION); + uint16_t romconfig_check = get_uint16(sl, cc, AO_ROMCONFIG_CHECK); if (romconfig_version != (uint16_t) ~romconfig_check) { fprintf (stderr, "Device has not been flashed before\n"); @@ -449,6 +219,8 @@ check_flashed(stlink_t *sl) } static const struct option options[] = { + { .name = "stlink", .has_arg = 0, .val = 'S' }, + { .name = "tty", .has_arg = 1, .val = 'T' }, { .name = "device", .has_arg = 1, .val = 'D' }, { .name = "cal", .has_arg = 1, .val = 'c' }, { .name = "serial", .has_arg = 1, .val = 's' }, @@ -457,13 +229,17 @@ static const struct option options[] = { static void usage(char *program) { - fprintf(stderr, "usage: %s [--cal=] [--serial=] file.elf\n", program); + fprintf(stderr, "usage: %s [--stlink] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } void -done(stlink_t *sl, int code) +done(stlink_t *sl, struct cc_usb *cc, int code) { + if (cc) { +/* cc_usb_printf(cc, "a\n"); */ + cc_usb_close(cc); + } if (sl) { stlink_reset(sl); stlink_run(sl); @@ -473,6 +249,17 @@ done(stlink_t *sl, int code) 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) { @@ -491,13 +278,20 @@ main (int argc, char **argv) char cal_int[4]; char *cal_end; int c; - stlink_t *sl; + stlink_t *sl = NULL; int was_flashed = 0; - struct load *load; + struct hex_image *load; int tries; + struct cc_usb *cc = NULL; + int use_stlink = 0; + char *tty = NULL; + int success; - while ((c = getopt_long(argc, argv, "D:c:s:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "T:D:c:s:S", options, NULL)) != -1) { switch (c) { + case 'T': + tty = optarg; + break; case 'D': device = optarg; break; @@ -511,6 +305,9 @@ main (int argc, char **argv) if (serial_end == optarg || *serial_end != '\0') usage(argv[0]); break; + case 'S': + use_stlink = 1; + break; default: usage(argv[0]); break; @@ -521,91 +318,145 @@ main (int argc, char **argv) if (filename == NULL) usage(argv[0]); - /* - * Open the source file and load the symbols and - * flash data - */ - - e = ao_open_elf(filename); - if (!e) { - fprintf(stderr, "Cannot open file \"%s\"\n", filename); - exit(1); - } - - if (!find_symbols(e)) { - fprintf(stderr, "Cannot find symbols in \"%s\"\n", filename); - exit(1); - } + if (ends_with (filename, ".elf")) { + load = ao_load_elf(filename); + } else if (ends_with (filename, ".ihx")) { + int i; + load = ccdbg_hex_load(filename); + for (i = 0; i < ao_num_symbols; i++) + ao_symbols[i].addr = ao_symbols[i].default_addr; + } else + usage(argv[0]); - if (!(load = get_load(e))) { - fprintf(stderr, "Cannot find program data in \"%s\"\n", filename); - exit(1); - } - - /* Connect to the programming dongle - */ + if (use_stlink) { + /* Connect to the programming dongle + */ - for (tries = 0; tries < 3; tries++) { - if (device) { - sl = stlink_v1_open(50); - } else { - sl = stlink_open_usb(50); + for (tries = 0; tries < 3; tries++) { + if (device) { + sl = stlink_v1_open(50); + } else { + sl = stlink_open_usb(50); + } + if (!sl) { + fprintf (stderr, "No STLink devices present\n"); + done (sl, NULL, 1); + } + + if (sl->chip_id != 0) + break; + stlink_reset(sl); + stlink_close(sl); + sl = NULL; } if (!sl) { - fprintf (stderr, "No STLink devices present\n"); - done (sl, 1); + fprintf (stderr, "Debugger connection failed\n"); + exit(1); } - if (sl->chip_id != 0) - break; - stlink_reset(sl); - stlink_close(sl); - } - if (sl->chip_id == 0) { - fprintf (stderr, "Debugger connection failed\n"); - done(sl, 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, NULL, 1); + } - /* Verify that the loaded image fits entirely within device flash - */ - if (load->addr < sl->flash_base || - sl->flash_base + sl->flash_size < load->addr + load->len) { - fprintf (stderr, "\%s\": Invalid memory range 0x%08x - 0x%08x\n", filename, - load->addr, load->addr + load->len); - 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); + } else { + int is_loader; + int tries; + + for (tries = 0; tries < 3; tries++) { + char *this_tty = tty; + if (!this_tty) + this_tty = cc_usbdevs_find_by_arg(device, "AltosFlash"); + if (!this_tty) + this_tty = cc_usbdevs_find_by_arg(device, "MegaMetrum"); + if (!this_tty) + this_tty = getenv("ALTOS_TTY"); + if (!this_tty) + this_tty="/dev/ttyACM0"; + + cc = cc_usb_open(this_tty); + + if (!cc) + exit(1); + cc_usb_printf(cc, "v\n"); + is_loader = 0; + for (;;) { + char line[256]; + cc_usb_getline(cc, line, sizeof(line)); + if (!strncmp(line, "altos-loader", 12)) + is_loader = 1; + if (!strncmp(line, "software-version", 16)) + break; + } + if (is_loader) + break; + printf ("rebooting to loader\n"); + cc_usb_printf(cc, "L\n"); + cc_usb_close(cc); + sleep(1); + cc = NULL; + } + if (!is_loader) { + fprintf(stderr, "Cannot switch to boot loader\n"); + exit(1); + } + { + uint8_t check[256]; + int i = 0; + + ao_self_block_read(cc, 0x08002000, check); + for (;;) { + uint8_t block[256]; + putchar ('.'); + if (++i == 40) { + putchar('\n'); + i = 0; + } + fflush(stdout); + ao_self_block_write(cc, 0x08002000, block); + ao_self_block_read(cc, 0x08002000, block); + if (memcmp(block, check, 256/me ta) != 0) { + fprintf (stderr, "read differed\n"); + exit(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); - /* Go fetch existing config values * if available */ - was_flashed = check_flashed(sl); + was_flashed = check_flashed(sl, cc); if (!serial) { if (!was_flashed) { fprintf (stderr, "Must provide serial number\n"); - done(sl, 1); + done(sl, cc, 1); } - serial = get_uint16(sl, AO_SERIAL_NUMBER); + serial = get_uint16(sl, cc, AO_SERIAL_NUMBER); if (!serial || serial == 0xffff) { fprintf (stderr, "Invalid existing serial %d\n", serial); - done(sl, 1); + done(sl, cc, 1); } } if (!cal && AO_RADIO_CAL && was_flashed) { - cal = get_uint32(sl, AO_RADIO_CAL); + cal = get_uint32(sl, cc, AO_RADIO_CAL); if (!cal || cal == 0xffffffff) { fprintf (stderr, "Invalid existing rf cal %d\n", cal); - done(sl, 1); + done(sl, cc, 1); } } @@ -618,32 +469,31 @@ main (int argc, char **argv) if (!rewrite(load, AO_SERIAL_NUMBER, serial_int, sizeof (serial_int))) { fprintf(stderr, "Cannot rewrite serial integer at %08x\n", AO_SERIAL_NUMBER); - done(sl, 1); + done(sl, cc, 1); } if (AO_USB_DESCRIPTORS) { - unsigned usb_descriptors; - usb_descriptors = AO_USB_DESCRIPTORS - load->addr; + uint32_t usb_descriptors = AO_USB_DESCRIPTORS - load->address; string_num = 0; - while (load->buf[usb_descriptors] != 0 && usb_descriptors < load->len) { - if (load->buf[usb_descriptors+1] == AO_USB_DESC_STRING) { + while (load->data[usb_descriptors] != 0 && usb_descriptors < load->length) { + if (load->data[usb_descriptors+1] == AO_USB_DESC_STRING) { ++string_num; if (string_num == 4) break; } - usb_descriptors += load->buf[usb_descriptors]; + usb_descriptors += load->data[usb_descriptors]; } - if (usb_descriptors >= load->len || load->buf[usb_descriptors] == 0 ) { + if (usb_descriptors >= load->length || load->data[usb_descriptors] == 0 ) { fprintf(stderr, "Cannot rewrite serial string at %08x\n", AO_USB_DESCRIPTORS); - done(sl, 1); + done(sl, cc, 1); } - serial_ucs2_len = load->buf[usb_descriptors] - 2; + serial_ucs2_len = load->data[usb_descriptors] - 2; serial_ucs2 = malloc(serial_ucs2_len); if (!serial_ucs2) { fprintf(stderr, "Malloc(%d) failed\n", serial_ucs2_len); - done(sl, 1); + done(sl, cc, 1); } s = serial; for (i = serial_ucs2_len / 2; i; i--) { @@ -651,9 +501,9 @@ main (int argc, char **argv) serial_ucs2[i * 2 - 2] = (s % 10) + '0'; s /= 10; } - if (!rewrite(load, usb_descriptors + 2 + load->addr, serial_ucs2, serial_ucs2_len)) { + if (!rewrite(load, usb_descriptors + 2 + load->address, serial_ucs2, serial_ucs2_len)) { fprintf (stderr, "Cannot rewrite USB descriptor at %08x\n", AO_USB_DESCRIPTORS); - done(sl, 1); + done(sl, cc, 1); } } @@ -671,10 +521,15 @@ main (int argc, char **argv) /* And flash the resulting image to the device */ - if (stlink_write_flash(sl, load->addr, load->buf, load->len) < 0) { + if (cc) + success = ao_self_write(cc, load); + else + 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, cc, 1); } - done(sl, 0); + done(sl, cc, 0); } diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h new file mode 100644 index 00000000..2618b7f3 --- /dev/null +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -0,0 +1,45 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_STMLOAD_H_ +#define _AO_STMLOAD_H_ + +struct sym { + unsigned addr; + unsigned default_addr; + char *name; + int required; +}; + +extern struct 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]); + +struct hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); + +int +ao_self_write(struct cc_usb *cc, struct hex_image *image); + +#endif /* _AO_STMLOAD_H_ */ -- cgit v1.2.3 From 21356aec543dd85426a52469426351ce006a17dd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Mar 2013 16:16:55 -0700 Subject: ao-tools/ao-stmload: Remove IRC dregs in source code oops. Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index b9bf4392..c983df26 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -427,7 +427,7 @@ main (int argc, char **argv) fflush(stdout); ao_self_block_write(cc, 0x08002000, block); ao_self_block_read(cc, 0x08002000, block); - if (memcmp(block, check, 256/me ta) != 0) { + if (memcmp(block, check, 256) != 0) { fprintf (stderr, "read differed\n"); exit(1); } -- cgit v1.2.3 From 9029722708b54826aa9374555470cb40922c5da5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Apr 2013 20:56:00 -0500 Subject: ao-tools: reboot to loader now uses 'X' instead of 'L' 'L' is used by lots of other commands; switch to 'X' which is free. Sigh. Someday we'll have words for commands instead of just letters Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index c983df26..35d4b299 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -403,7 +403,7 @@ main (int argc, char **argv) if (is_loader) break; printf ("rebooting to loader\n"); - cc_usb_printf(cc, "L\n"); + cc_usb_printf(cc, "X\n"); cc_usb_close(cc); sleep(1); cc = NULL; -- cgit v1.2.3 From 9ae987073f90402821120dbe962fceb4fc9f5435 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Apr 2013 20:59:12 -0500 Subject: ao-tools/ao-stmload: application base moved to 0x08001000 And, use a symbolic name so it can be easily moved in the future Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 16 ++++++++-------- ao-tools/ao-stmload/ao-stmload.h | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 35d4b299..130f8707 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -36,19 +36,19 @@ struct sym ao_symbols[] = { - { 0, 0x08002100, "ao_romconfig_version", 1 }, + { 0, AO_BOOT_APPLICATION_BASE + 0x100, "ao_romconfig_version", 1 }, #define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) - { 0, 0x08002102, "ao_romconfig_check", 1 }, + { 0, AO_BOOT_APPLICATION_BASE + 0x102, "ao_romconfig_check", 1 }, #define AO_ROMCONFIG_CHECK (ao_symbols[1].addr) - { 0, 0x08002104, "ao_serial_number", 1 }, + { 0, AO_BOOT_APPLICATION_BASE + 0x104, "ao_serial_number", 1 }, #define AO_SERIAL_NUMBER (ao_symbols[2].addr) - { 0, 0x08002108, "ao_radio_cal", 0 }, + { 0, AO_BOOT_APPLICATION_BASE + 0x108, "ao_radio_cal", 0 }, #define AO_RADIO_CAL (ao_symbols[3].addr) - { 0, 0x0800210c, "ao_usb_descriptors", 0 }, + { 0, AO_BOOT_APPLICATION_BASE + 0x10c, "ao_usb_descriptors", 0 }, #define AO_USB_DESCRIPTORS (ao_symbols[4].addr) }; @@ -416,7 +416,7 @@ main (int argc, char **argv) uint8_t check[256]; int i = 0; - ao_self_block_read(cc, 0x08002000, check); + ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, check); for (;;) { uint8_t block[256]; putchar ('.'); @@ -425,8 +425,8 @@ main (int argc, char **argv) i = 0; } fflush(stdout); - ao_self_block_write(cc, 0x08002000, block); - ao_self_block_read(cc, 0x08002000, block); + ao_self_block_write(cc, AO_BOOT_APPLICATION_BASE, block); + ao_self_block_read(cc, AO_BOOT_APPLICATION_BASE, block); if (memcmp(block, check, 256) != 0) { fprintf (stderr, "read differed\n"); exit(1); diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h index 2618b7f3..754c1c5b 100644 --- a/ao-tools/ao-stmload/ao-stmload.h +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -25,6 +25,8 @@ struct sym { int required; }; +#define AO_BOOT_APPLICATION_BASE 0x08001000 + extern struct sym ao_symbols[]; extern int ao_num_symbols; -- cgit v1.2.3 From 1695f6af46ea647119d651fc09c97d604d08c736 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 27 Apr 2013 00:26:11 -0700 Subject: ao-tools/ao-stmload: Add --verbose flag This dumps out the serial communication so you can see where things go wrong. Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-selfload.c | 25 +++++++++++++++++-------- ao-tools/ao-stmload/ao-stmload.c | 16 ++++++++++++++-- ao-tools/ao-stmload/ao-stmload.h | 2 ++ ao-tools/lib/cc-usb.c | 8 +++++--- 4 files changed, 38 insertions(+), 13 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/ao-selfload.c b/ao-tools/ao-stmload/ao-selfload.c index b3105b21..95667dca 100644 --- a/ao-tools/ao-stmload/ao-selfload.c +++ b/ao-tools/ao-stmload/ao-selfload.c @@ -26,18 +26,24 @@ #include "ccdbg.h" #include "ao-stmload.h" +int ao_self_verbose; + +#define TRACE(...) if (ao_self_verbose) printf (__VA_ARGS__) + void ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]) { int byte; cc_usb_sync(cc); cc_usb_printf(cc, "R %x\n", address); -// printf ("read %08x\n", address); for (byte = 0; byte < 0x100; byte++) { block[byte] = cc_usb_getchar(cc); -// printf (" %02x", block[byte]); -// if ((byte & 0xf) == 0xf) -// printf ("\n"); + } + TRACE ("\nread %08x\n", address); + for (byte = 0; byte < 0x100; byte++) { + TRACE (" %02x", block[byte]); + if ((byte & 0xf) == 0xf) + TRACE ("\n"); } } @@ -47,12 +53,14 @@ ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) int byte; cc_usb_sync(cc); cc_usb_printf(cc, "W %x\n", address); -// printf ("write %08x\n", address); + TRACE ("write %08x\n", address); + for (byte = 0; byte < 0x100; byte++) { + TRACE (" %02x", block[byte]); + if ((byte & 0xf) == 0xf) + TRACE ("\n"); + } for (byte = 0; byte < 0x100; byte++) { cc_usb_printf(cc, "%c", block[byte]); -// printf (" %02x", block[byte]); -// if ((byte & 0xf) == 0xf) -// printf ("\n"); } } @@ -114,5 +122,6 @@ ao_self_write(struct cc_usb *cc, struct hex_image *image) putchar('.'); fflush(stdout); } printf("done\n"); + cc_usb_printf(cc,"a\n"); return 1; } diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index 130f8707..dd25f07f 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -224,12 +224,13 @@ static const struct option options[] = { { .name = "device", .has_arg = 1, .val = 'D' }, { .name = "cal", .has_arg = 1, .val = 'c' }, { .name = "serial", .has_arg = 1, .val = 's' }, + { .name = "verbose", .has_arg = 0, .val = 'v' }, { 0, 0, 0, 0}, }; static void usage(char *program) { - fprintf(stderr, "usage: %s [--stlink] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); + fprintf(stderr, "usage: %s [--stlink] [--verbose] [--device=] [-tty=] [--cal=] [--serial=] file.{elf,ihx}\n", program); exit(1); } @@ -286,8 +287,9 @@ main (int argc, char **argv) int use_stlink = 0; char *tty = NULL; int success; + int verbose = 0; - while ((c = getopt_long(argc, argv, "T:D:c:s:S", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "T:D:c:s:Sv", options, NULL)) != -1) { switch (c) { case 'T': tty = optarg; @@ -308,12 +310,20 @@ main (int argc, char **argv) case 'S': use_stlink = 1; break; + case 'v': + verbose++; + break; default: usage(argv[0]); break; } } + ao_self_verbose = verbose; + + if (verbose > 1) + ccdbg_add_debug(CC_DEBUG_BITBANG); + filename = argv[optind]; if (filename == NULL) usage(argv[0]); @@ -412,6 +422,7 @@ main (int argc, char **argv) fprintf(stderr, "Cannot switch to boot loader\n"); exit(1); } +#if 0 { uint8_t check[256]; int i = 0; @@ -433,6 +444,7 @@ main (int argc, char **argv) } } } +#endif } /* Go fetch existing config values diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h index 754c1c5b..98884535 100644 --- a/ao-tools/ao-stmload/ao-stmload.h +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -44,4 +44,6 @@ ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); int ao_self_write(struct cc_usb *cc, struct hex_image *image); +extern int ao_self_verbose; + #endif /* _AO_STMLOAD_H_ */ diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index 485583f9..d7ac138c 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -123,9 +123,10 @@ cc_handle_hex_read(struct cc_usb *cc) static void cc_usb_dbg(int indent, uint8_t *bytes, int len) { - int eol = 1; + static int eol = 1; int i; uint8_t c; + ccdbg_debug(CC_DEBUG_BITBANG, "<<<%d bytes>>>", len); while (len--) { c = *bytes++; if (eol) { @@ -135,10 +136,12 @@ cc_usb_dbg(int indent, uint8_t *bytes, int len) } switch (c) { case '\r': - ccdbg_debug(CC_DEBUG_BITBANG, "^M"); + ccdbg_debug(CC_DEBUG_BITBANG, "\\r"); break; case '\n': eol = 1; + ccdbg_debug(CC_DEBUG_BITBANG, "\\n\n"); + break; default: if (c < ' ' || c > '~') ccdbg_debug(CC_DEBUG_BITBANG, "\\%02x", c); @@ -193,7 +196,6 @@ _cc_usb_sync(struct cc_usb *cc, int wait_for_input) ret = read(cc->fd, cc->in_buf + cc->in_count, CC_IN_BUF - cc->in_count); if (ret > 0) { - int i; cc_usb_dbg(24, cc->in_buf + cc->in_count, ret); cc->in_count += ret; if (cc->hex_count) -- cgit v1.2.3