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/lib/Makefile.am | 1 + ao-tools/lib/cc.h | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) (limited to 'ao-tools/lib') 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 -- 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/lib') 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/lib') 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/lib') 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 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/lib') 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 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/lib') 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/lib') 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 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/lib') 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