diff options
40 files changed, 1473 insertions, 68 deletions
| diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 32d02f21..5598a603 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -205,6 +205,8 @@ public class AltosState {  				pad_alt = ground_altitude;  		} +		data.new_gps = false; +  		gps_waiting = MIN_PAD_SAMPLES - npad;  		if (gps_waiting < 0)  			gps_waiting = 0; diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index c06f57ec..2facf38a 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -85,15 +85,15 @@ public class AltosInfoTable extends JTable {  	}  	void info_add_deg(int col, String name, double v, int pos, int neg) { -		//int	c = pos; +		int	c = pos;  		if (v < 0) { -			//c = neg; +			c = neg;  			v = -v;  		}  		double	deg = Math.floor(v);  		double	min = (v - deg) * 60; -		info_add_row(col, name, String.format("%3.0f°%08.5f'", deg, min)); +		info_add_row(col, name, String.format("%c %3.0f°%08.5f'", c, deg, min));  	}  	void info_finish() { diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java index 5c589c02..5f3a2eef 100644 --- a/altosuilib/AltosUIGraph.java +++ b/altosuilib/AltosUIGraph.java @@ -91,13 +91,19 @@ public class AltosUIGraph implements AltosUnitsListener {  	}  	public void resetData() { -		for (AltosUIGrapher g : graphers) +		for (AltosUIGrapher g : graphers) {  			g.clear(); +			g.setNotify(false); +		}  		if (dataSet != null) {  			for (AltosUIDataPoint dataPoint : dataSet.dataPoints())  				for (AltosUIGrapher g : graphers)  					g.add(dataPoint);  		} +		for (AltosUIGrapher g : graphers) { +			g.setNotify(true); +			g.fireSeriesChanged(); +		}  	}  	public void units_changed(boolean imperial_units) { diff --git a/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java index c627fec5..8f0ce801 100644 --- a/altosuilib/AltosUIGrapher.java +++ b/altosuilib/AltosUIGrapher.java @@ -43,4 +43,8 @@ interface AltosUIGrapher {  	public abstract void add(AltosUIDataPoint dataPoint);  	public abstract void set_enable(boolean enable); + +	public abstract void setNotify(boolean notify); + +	public abstract void fireSeriesChanged();  } diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java index e2eb9028..0949be6f 100644 --- a/altosuilib/AltosUIMarker.java +++ b/altosuilib/AltosUIMarker.java @@ -100,6 +100,12 @@ public class AltosUIMarker implements AltosUIGrapher {  		this.enabled = enable;  	} +	public void setNotify(boolean notify) { +	} + +	public void fireSeriesChanged() { +	} +  	public AltosUIMarker (int fetch, Color color, XYPlot plot) {  		this(fetch, color, plot, true);  	} diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 871b8205..e4df2e63 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 ao-edit-telem 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 <keithp@keithp.com> +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License along +.\" with this program; if not, write to the Free Software Foundation, Inc., +.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +.\" +.\" +.TH AO-DUMPFLASH 1 "ao-dumpflash" "" +.SH NAME +ao-dumpflash \- Fetch flash memory contents from AltOS device +.SH SYNOPSIS +.B "ao-dumpflash" +[\--tty \fItty-device\fP] +[\--device \fIaltos-device\fP] +[\--output \fIoutput-file\fP] +[\--remote\fP] +[\--frequency \fIfrequency\fP] +[\--call \fIcallsign\fP] +.SH OPTIONS +.TP +\-T tty-device | --tty tty-device +This selects which tty device ao-dumpflash uses to communicate with +the target device. +.TP +\-D AltOS-device | --device AltOS-device +Search for a connected device. This requires an argument of one of the +following forms: +.IP +TeleMetrum:2 +.br +TeleMetrum +.br +2 +.IP +Leaving out the product name will cause the tool to select a suitable +product, leaving out the serial number will cause the tool to match +one of the available devices. +.TP +\-o output-file | --output output-file +Write flash contents to the specified file rather than stdout. +.TP +\-R | --remote +This uses the command radio link to download the flash from TeleMetrum +through a TeleDongle. +.TP +\-F frequency | --frequency frequency +Specifies the radio frequency to use for remote communications in +kHz. Default is 434550. +.TP +\-C callsign | --call callsign +Specifies the callsign to use for remote communications. Default is N0CALL. +.SH DESCRIPTION +.I ao-dumpflash +downloads the entire flash memory contents from a connected AltOS device and writes +it to either stdout or the specified output file. +.SH USAGE +.I ao-dumpflash +connects to the specified target device and dumps the flash. +.SH AUTHOR +Keith Packard 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 <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <getopt.h> +#include <string.h> +#include "cc-usb.h" +#include "cc.h" + +#define NUM_BLOCK	512 + +static const struct option options[] = { +	{ .name = "tty", .has_arg = 1, .val = 'T' }, +	{ .name = "device", .has_arg = 1, .val = 'D' }, +	{ .name = "remote", .has_arg = 0, .val = 'R' }, +	{ .name = "frequency", .has_arg = 1, .val = 'F' }, +	{ .name = "call", .has_arg = 1, .val = 'C' }, +	{ .name = "output", .has_arg = 1, .val = 'o' }, +	{ 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ +	fprintf(stderr, "usage: %s [--tty <tty-name>] [--device <device-name>] [--remote] [--frequency <radio-frequency>] [--call <radio-callsign>]\n", program); +	exit(1); +} + +int +main (int argc, char **argv) +{ +	struct cc_usb	*cc; +	char		*tty = NULL; +	char		*device = NULL; +	int		c; +	char		line[8192]; +	FILE		*out; +	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/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 <keithp@keithp.com> +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License along +.\" with this program; if not, write to the Free Software Foundation, Inc., +.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +.\" +.\" +.TH AO-EDIT-TELEM 1 "ao-edit-telem" "" +.SH NAME +ao-edit-telem \- Edit telemetry file, creating new telemetry stream +.SH SYNOPSIS +.B "ao-edit-telem" +[\--lat=<pad-lat>] +[\--lon=<pad-lon>] +{flight.telem} +.SH DESCRIPTION +.I ao-edit-telem +reads the specified telemetry log and produces a new telemetry log, +changed as directed by the options provided. +output. +.SH AUTHOR +Keith Packard 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 <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#define _GNU_SOURCE +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <getopt.h> +#include "cc.h" + +static const struct option options[] = { +	{ .name = "lat", .has_arg = 1, .val = 'L' }, +	{ .name = "lon", .has_arg = 1, .val = 'l' }, +	{ 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ +	fprintf(stderr, "usage: %s [--lat <pad-lat>] [--lon <pad-lon>]\n" +		"\t{flight-log} ...\n", program); +	exit(1); +} + +#define bool(b)	((b) ? "true" : "false") + +struct telem_ent { +	struct telem_ent	*next; +	union ao_telemetry_all	telem; +}; + +static struct telem_ent *pad, **last = &pad; + +static void +save_telem(union ao_telemetry_all *telem) +{ +	struct telem_ent *t = malloc (sizeof *t); +	t->telem = *telem; +	t->next = NULL; +	*last = t; +	last = &t->next; +} + +static void +dump_telem(union ao_telemetry_all *telem) +{ +	char s[CC_TELEMETRY_BUFSIZE]; + +	cc_telemetry_unparse(telem, s); +	printf("%s\n", s); +} + +double	pad_lat = 0, pad_lon = 0; +double	target_pad_lat = 0, target_pad_lon = 0; +double	lat_off = 0, lon_off = 0; +int pending = 1; + +static void +dump_saved(void); + +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/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 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 a1c8c4fc..f9a892df 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl  dnl Process this file with autoconf to create configure.  AC_PREREQ(2.57) -AC_INIT([altos], 1.1.9.3) +AC_INIT([altos], 1.2)  AC_CONFIG_SRCDIR([src/core/ao.h])  AM_INIT_AUTOMAKE([foreign dist-bzip2])  AM_MAINTAINER_MODE @@ -181,6 +181,8 @@ 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-tools/ao-edit-telem/Makefile  ao-utils/Makefile  src/Version  ]) diff --git a/doc/Makefile b/doc/Makefile index 59fd4ebb..7c4da29e 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -8,8 +8,9 @@ RELNOTES=\  	release-notes-0.9.html \  	release-notes-0.9.2.html \  	release-notes-1.0.1.html \ +	release-notes-1.1.html \  	release-notes-1.1.1.html \ -	release-notes-1.1.html +	release-notes-1.2.html  RELNOTES_XSL=$(RELNOTES:.html=.xsl)  HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $(RELNOTES) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 9fdd6b07..c5c08d4e 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -386,6 +386,36 @@ NAR #88757, TRA #12200          tower with a screw-driver trying to turn on your avionics before           installing igniters!        </para> +      <para> +	TeleMini is configured via the radio link. Of course, that +	means you need to know the TeleMini radio configuration values +	or you won't be able to communicate with it. For situations +	when you don't have the radio configuration values, TeleMini +	offers an 'emergency recovery' mode. In this mode, TeleMini is +	configured as follows: +	<itemizedlist> +	  <listitem> +	    Sets the radio frequency to 434.550MHz +	  </listitem> +	  <listitem> +	    Sets the radio calibration back to the factory value. +	  </listitem> +	  <listitem> +	    Sets the callsign to N0CALL +	  </listitem> +	  <listitem> +	    Does not go to 'pad' mode after five seconds. +	  </listitem> +	</itemizedlist> +      </para> +      <para> +	To get into 'emergency recovery' mode, first find the row of +	four small holes opposite the switch wiring. Using a short +	piece of small gauge wire, connect the outer two holes +	together, then power TeleMini up. Once the red LED is lit, +	disconnect the wire and the board should signal that it's in +	'idle' mode after the initial five second startup period. +      </para>      </section>      <section>        <title>GPS </title> @@ -2649,6 +2679,7 @@ NAR #88757, TRA #12200    <appendix        xmlns:xi="http://www.w3.org/2001/XInclude">      <title>Release Notes</title> +    <simplesect><title>Version 1.2</title><xi:include	href="release-notes-1.2.xsl"  xpointer="xpointer(/article/*)"/></simplesect>      <simplesect><title>Version 1.1.1</title><xi:include	href="release-notes-1.1.1.xsl"  xpointer="xpointer(/article/*)"/></simplesect>      <simplesect><title>Version 1.1</title><xi:include	href="release-notes-1.1.xsl"  xpointer="xpointer(/article/*)"/></simplesect>      <simplesect><title>Version 1.0.1</title><xi:include	href="release-notes-1.0.1.xsl"  xpointer="xpointer(/article/*)"/></simplesect> diff --git a/doc/release-notes-1.2.xsl b/doc/release-notes-1.2.xsl new file mode 100644 index 00000000..610fa1a2 --- /dev/null +++ b/doc/release-notes-1.2.xsl @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" +"/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd"> + +<article> +  <para> +    Version 1.2 is a minor release. It provides a few new features in AltosUI +    and the AltOS firmware and fixes bugs. +  </para> +  <para> +    AltOS Firmware Changes +    <itemizedlist> +      <listitem> +	In TeleMini recovery mode (when booted with the outer two +	debug pins connected together), the radio parameters are also +	set back to defaults (434.550MHz, N0CALL, factory radio cal). +      </listitem> +      <listitem> +	Add support for reflashing the SkyTraq GPS chips. This +	requires special host-side code which currently only exists +	for Linux. +      </listitem> +      <listitem> +	Add MicroPeak support. This includes support for the ATtiny85 +	processor and adaptations to the core code to allow for +	devices too small to run the multi-tasking scheduler. +      </listitem> +      <listitem> +	Correct Kalman filter model error covariance matrix. The +	values used previously assumed continuous measurements instead +	of discrete measurements. +      </listitem> +    </itemizedlist> +  </para> +  <para> +    AltosUI Changes +    <itemizedlist> +      <listitem> +	Handle missing GPS lock in 'Descent' tab. Previously, if the +	GPS position of the pad was unknown, an exception would be +	raised, breaking the Descent tab contents. +      </listitem> +      <listitem> +	Add preliminary MegaMetrum support, including configuration, +	data download and analysis. +      </listitem> +      <listitem> +	Improve the graph, adding tool-tips to show values near the +	cursor and making the displayed set of values configurable, +	adding all of the flight data as options while leaving the +	default settings alone so that the graph starts by showing +	height, speed and acceleration. +      </listitem> +      <listitem> +	Make the initial position of the AltosUI top level window +	configurable. Along with this change, the other windows will +	pop up at 'sensible' places now, instead of on top of one +	another. +      </listitem> +      <listitem> +	Add callsign to Monitor idle window and connecting +	dialogs. This makes it clear which callsign is being used so +	that the operator will be aware that it must match the flight +	computer value or no communication will work. +      </listitem> +      <listitem> +	When downloading flight data, display the block number so that +	the user has some sense of progress. Unfortunately, we don't +	know how many blocks will need to be downloaded, but at least +	it isn't just sitting there doing nothing for a long time. +      </listitem> +      <listitem> +	Add GPS data and a map to the graph window. This lets you see +	a complete summary of the flight without needing to 'replay' +	the whole thing. +      </listitem> +    </itemizedlist> +  </para> +  <para> +    Distribution Changes +    <itemizedlist> +      <listitem> +	Distribute Mac OS X packages in disk image ('.dmg') format to +	greatly simplify installation. +      </listitem> +      <listitem> +	Provide version numbers for the shared Java libraries to +	ensure that upgrades work properly, and to allow for multiple +	Altus Metrum software packages to be installed in the same +	directory at the same time. +      </listitem> +    </itemizedlist> +  </para> +</article> diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index ca56746a..2a41ef80 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -977,6 +977,24 @@ struct altos_file {  	OVERLAPPED			ov_write;  }; +#include <stdarg.h> + +static void +log_message(char *fmt, ...) +{ +	static	FILE *log = NULL; +	va_list	a; + +	if (!log) +		log = fopen("\\temp\\altos.txt", "w"); +	if (log) { +		va_start(a, fmt); +		vfprintf(log, fmt, a); +		va_end(a); +		fflush(log); +	} +} +  static void  _altos_set_last_windows_error(char *file, int line)  { @@ -990,7 +1008,7 @@ _altos_set_last_windows_error(char *file, int line)  		      sizeof (message) / sizeof (TCHAR),  		      NULL);  	if (error != ERROR_SUCCESS) -		printf ("%s:%d %s\n", file, line, message); +		log_message ("%s:%d %s\n", file, line, message);  	altos_set_last_error(error, message);  } @@ -1061,7 +1079,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  					       KEY_READ);  		if (dev_key == INVALID_HANDLE_VALUE) {  			altos_set_last_windows_error(); -			printf("cannot open device registry key\n");  			continue;  		} @@ -1077,7 +1094,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  						 symbolic, &symbolic_len);  			if (result != 0) {  				altos_set_last_windows_error(); -				printf("cannot find SymbolicName value\n");  				RegCloseKey(dev_key);  				continue;  			} @@ -1097,7 +1113,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  		RegCloseKey(dev_key);  		if (result != 0) {  			altos_set_last_windows_error(); -			printf("failed to get PortName\n");  			continue;  		} @@ -1113,7 +1128,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  						     &friendlyname_len))  		{  			altos_set_last_windows_error(); -			printf("Failed to get friendlyname\n");  			continue;  		}  		device->vendor = vid; @@ -1125,10 +1139,8 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  		return 1;  	}  	result = GetLastError(); -	if (result != ERROR_NO_MORE_ITEMS) { +	if (result != ERROR_NO_MORE_ITEMS)  		altos_set_last_windows_error(); -		printf ("SetupDiEnumDeviceInfo failed error %d\n", (int) result); -	}  	return 0;  } @@ -1187,6 +1199,7 @@ altos_wait_read(struct altos_file *file, int timeout)  		return LIBALTOS_TIMEOUT;  		break;  	default: +		altos_set_last_windows_error();  		return LIBALTOS_ERROR;  	}  	return LIBALTOS_SUCCESS; @@ -1224,7 +1237,6 @@ altos_flush(struct altos_file *file)  		if (!WriteFile(file->handle, data, used, &put, &file->ov_write)) {  			if (GetLastError() != ERROR_IO_PENDING) {  				altos_set_last_windows_error(); -				printf ("\tflush write error\n");  				return LIBALTOS_ERROR;  			}  			ret = WaitForSingleObject(file->ov_write.hEvent, INFINITE); @@ -1232,13 +1244,11 @@ altos_flush(struct altos_file *file)  			case WAIT_OBJECT_0:  				if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE)) {  					altos_set_last_windows_error(); -					printf ("\tflush result error\n");  					return LIBALTOS_ERROR;  				}  				break;  			default:  				altos_set_last_windows_error(); -				printf ("\tflush wait error\n");  				return LIBALTOS_ERROR;  			}  		} @@ -1249,30 +1259,88 @@ altos_flush(struct altos_file *file)  	return LIBALTOS_SUCCESS;  } +static HANDLE +open_serial(char *full_name) +{ +	HANDLE	handle; +	DCB	dcb; + +	handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE, +			    0, NULL, OPEN_EXISTING, +			    FILE_FLAG_OVERLAPPED, NULL); + +	if (handle == INVALID_HANDLE_VALUE) { +		altos_set_last_windows_error(); +		return INVALID_HANDLE_VALUE; +	} + +	if (!GetCommState(handle, &dcb)) { +		altos_set_last_windows_error(); +		CloseHandle(handle); +		return INVALID_HANDLE_VALUE; +	} +	dcb.BaudRate = CBR_9600; +	dcb.fBinary = TRUE; +	dcb.fParity = FALSE; +	dcb.fOutxCtsFlow = FALSE; +	dcb.fOutxDsrFlow = FALSE; +	dcb.fDtrControl = DTR_CONTROL_ENABLE; +	dcb.fDsrSensitivity = FALSE; +	dcb.fTXContinueOnXoff = FALSE; +	dcb.fOutX = FALSE; +	dcb.fInX = FALSE; +	dcb.fErrorChar = FALSE; +	dcb.fNull = FALSE; +	dcb.fRtsControl = RTS_CONTROL_ENABLE; +	dcb.fAbortOnError = FALSE; +	dcb.XonLim = 10; +	dcb.XoffLim = 10; +	dcb.ByteSize = 8; +	dcb.Parity = NOPARITY; +	dcb.StopBits = ONESTOPBIT; +	dcb.XonChar = 17; +	dcb.XoffChar = 19; +#if 0 +	dcb.ErrorChar = 0; +	dcb.EofChar = 0; +	dcb.EvtChar = 0; +#endif +	if (!SetCommState(handle, &dcb)) { +		altos_set_last_windows_error(); +		CloseHandle(handle); +		return INVALID_HANDLE_VALUE; +	} +	return handle; +} +  PUBLIC struct altos_file *  altos_open(struct altos_device *device)  {  	struct altos_file	*file = calloc (1, sizeof (struct altos_file));  	char	full_name[64];  	COMMTIMEOUTS timeouts; -	DCB	     dcb;  	if (!file)  		return NULL;  	strcpy(full_name, "\\\\.\\");  	strcat(full_name, device->path); -	file->handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE, -				  0, NULL, OPEN_EXISTING, -				  FILE_FLAG_OVERLAPPED, NULL); + +	file->handle = open_serial(full_name);  	if (file->handle == INVALID_HANDLE_VALUE) { -		altos_set_last_windows_error(); -		printf ("cannot open %s\n", full_name);  		free(file);  		return NULL;  	} -	file->ov_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); -	file->ov_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + +	/* The FTDI driver doesn't appear to work right unless you open it twice */ +	if (device->vendor == 0x0403) { +		CloseHandle(file->handle); +		file->handle = open_serial(full_name); +		if (file->handle == INVALID_HANDLE_VALUE) { +			free(file); +			return NULL; +		} +	}  	timeouts.ReadIntervalTimeout = MAXDWORD;  	timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; @@ -1281,10 +1349,8 @@ altos_open(struct altos_device *device)  	timeouts.WriteTotalTimeoutConstant = 0;  	SetCommTimeouts(file->handle, &timeouts); -	if (GetCommState(file->handle, &dcb)) { -		dcb.BaudRate = CBR_9600; -		(void) SetCommState(file->handle, &dcb); -	} +	file->ov_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +	file->ov_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  	return file;  } @@ -1330,8 +1396,10 @@ altos_getchar(struct altos_file *file, int timeout)  {  	int	ret;  	while (file->in_read == file->in_used) { -		if (file->handle == INVALID_HANDLE_VALUE) +		if (file->handle == INVALID_HANDLE_VALUE) { +			altos_set_last_windows_error();  			return LIBALTOS_ERROR; +		}  		ret = altos_fill(file, timeout);  		if (ret)  			return ret; diff --git a/src/Makefile b/src/Makefile index 67ad97d1..9e31e3ea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -29,7 +29,8 @@ AVRDIRS=\  	telescience-v0.1 telescience-pwm telepyro-v0.1 micropeak  ARMDIRS=\ -	megametrum-v0.1 megadongle-v0.1 stm-bringup stm-demo telelco-v0.1 +	megametrum-v0.1 megadongle-v0.1 stm-bringup stm-demo telelco-v0.1 \ +	telescience-v0.2  ifneq ($(shell which sdcc),)  	SUBDIRS += $(SDCCDIRS) diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index a400b8a0..15e9924d 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -18,22 +18,24 @@  #include "ao.h"  uint8_t -ao_spi_slave_recv(uint8_t *buf, uint8_t len) +ao_spi_slave_recv(void *buf, uint16_t len)  { +	uint8_t *b = buf;  	while (len--) {  		while (!(SPSR & (1 << SPIF)))  			if ((PINB & (1 << PINB0)))  				return 0; -		*buf++ = SPDR; +		*b++ = SPDR;  	}  	return 1;  }  void -ao_spi_slave_send(uint8_t *buf, uint8_t len) +ao_spi_slave_send(void *buf, uint16_t len)  { +	uint8_t *b = buf;  	while (len--) { -		SPDR = *buf++; +		SPDR = *b++;  		while (!(SPSR & (1 << SPIF)))  			if ((PINB & (1 << PINB0)))  				return; diff --git a/src/core/ao.h b/src/core/ao.h index df5bbf48..ce0bf5d1 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -299,10 +299,10 @@ ao_altitude_to_pa(alt_t alt);   */  uint8_t -ao_spi_slave_recv(uint8_t *buf, uint8_t len); +ao_spi_slave_recv(void *buf, uint16_t len);  void -ao_spi_slave_send(uint8_t *buf, uint8_t len); +ao_spi_slave_send(void *buf, uint16_t len);  void  ao_spi_slave_init(void); diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 8068740f..53bb5a62 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -38,7 +38,7 @@ extern const uint32_t	ao_radio_cal;  #define FOSC	32000000 -#define ao_radio_select()	ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_1MHz) +#define ao_radio_select()	ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz)  #define ao_radio_deselect()	ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS)  #define ao_radio_spi_send(d,l)	ao_spi_send((d), (l), AO_CC1120_SPI_BUS)  #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS) diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c index 059fc2c8..782d03f4 100644 --- a/src/drivers/ao_hmc5883.c +++ b/src/drivers/ao_hmc5883.c @@ -77,11 +77,11 @@ ao_hmc5883_sample(struct ao_hmc5883_sample *sample)  	ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE);  	ao_alarm(AO_MS_TO_TICKS(10)); -	cli(); +	ao_arch_block_interrupts();  	while (!ao_hmc5883_done)  		if (ao_sleep(&ao_hmc5883_done))  			++ao_hmc5883_missed_irq; -	sei(); +	ao_arch_release_interrupts();  	ao_clear_alarm();  	ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample)); @@ -109,7 +109,7 @@ ao_hmc5883_setup(void)  	ao_i2c_put(AO_HMC5883_I2C_INDEX);  	if (!present) -		ao_panic(AO_PANIC_SELF_TEST); +		ao_panic(AO_PANIC_SELF_TEST_HMC5883);  	ao_hmc5883_reg_write(HMC5883_CONFIG_A,  			     (HMC5883_CONFIG_A_MA_8 << HMC5883_CONFIG_A_MA) | diff --git a/src/megadongle-v0.1/ao_pins.h b/src/megadongle-v0.1/ao_pins.h index c766a48c..d460a490 100644 --- a/src/megadongle-v0.1/ao_pins.h +++ b/src/megadongle-v0.1/ao_pins.h @@ -78,6 +78,7 @@  #define HAS_SPI_2		1  #define SPI_2_PB13_PB14_PB15	1	/* Flash, Companion */  #define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz  #define SPI_2_PORT		(&stm_gpiob)  #define SPI_2_SCK_PIN		13 diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 64da41a9..4c645871 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -76,10 +76,12 @@  #define SPI_1_PA5_PA6_PA7	1	/* Barometer */  #define SPI_1_PB3_PB4_PB5	0  #define SPI_1_PE13_PE14_PE15	1	/* Accelerometer */ +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz  #define HAS_SPI_2		1  #define SPI_2_PB13_PB14_PB15	1	/* Flash, Companion */  #define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz  #define SPI_2_PORT		(&stm_gpiob)  #define SPI_2_SCK_PIN		13 diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index c9c7446e..07b4a19d 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -60,6 +60,7 @@  #define HAS_SPI_1		1  #define SPI_1_PB3_PB4_PB5	1 +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz  #define HAS_SPI_2		0 diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 87bbe73e..d1779307 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -23,7 +23,7 @@  /* PCLK is set to 16MHz (HCLK 32MHz, APB prescaler 2) */ -#define AO_SPI_SPEED_8MHz	STM_SPI_CR1_BR_PCLK_2	/* This doesn't appear to work */ +#define AO_SPI_SPEED_8MHz	STM_SPI_CR1_BR_PCLK_2  #define AO_SPI_SPEED_4MHz	STM_SPI_CR1_BR_PCLK_4  #define AO_SPI_SPEED_2MHz	STM_SPI_CR1_BR_PCLK_8  #define AO_SPI_SPEED_1MHz	STM_SPI_CR1_BR_PCLK_16 @@ -32,7 +32,7 @@  #define AO_SPI_SPEED_125kHz	STM_SPI_CR1_BR_PCLK_128  #define AO_SPI_SPEED_62500Hz	STM_SPI_CR1_BR_PCLK_256 -#define AO_SPI_SPEED_FAST	AO_SPI_SPEED_4MHz +#define AO_SPI_SPEED_FAST	AO_SPI_SPEED_8MHz  /* Companion bus wants something no faster than 200kHz */ diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 599d7ee0..7b4af964 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -425,12 +425,21 @@ ao_spi_init(void)  #if HAS_SPI_1  # if SPI_1_PA5_PA6_PA7  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); +	stm_ospeedr_set(&stm_gpioa, 5, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioa, 6, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioa, 7, SPI_1_OSPEEDR);  # endif  # if SPI_1_PB3_PB4_PB5  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +	stm_ospeedr_set(&stm_gpiob, 3, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 4, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 5, SPI_1_OSPEEDR);  # endif  # if SPI_1_PE13_PE14_PE15  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); +	stm_ospeedr_set(&stm_gpioe, 13, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioe, 14, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioe, 15, SPI_1_OSPEEDR);  # endif  	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN);  	ao_spi_index[0] = AO_SPI_CONFIG_NONE; @@ -440,9 +449,15 @@ ao_spi_init(void)  #if HAS_SPI_2  # if SPI_2_PB13_PB14_PB15  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +	stm_ospeedr_set(&stm_gpiob, 13, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 14, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 15, SPI_2_OSPEEDR);  # endif  # if SPI_2_PD1_PD3_PD4  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); +	stm_ospeedr_set(&stm_gpiod, 1, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiod, 3, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiod, 4, SPI_2_OSPEEDR);  # endif  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN);  	ao_spi_index[1] = AO_SPI_CONFIG_NONE; diff --git a/src/stm/ao_spi_stm_slave.c b/src/stm/ao_spi_stm_slave.c new file mode 100644 index 00000000..98022442 --- /dev/null +++ b/src/stm/ao_spi_stm_slave.c @@ -0,0 +1,339 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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> + +struct ao_spi_stm_slave_info { +	uint8_t	miso_dma_index; +	uint8_t mosi_dma_index; +	struct stm_spi *stm_spi; +}; + +static uint8_t		ao_spi_slave_mutex[STM_NUM_SPI]; +static uint8_t		ao_spi_slave_index[STM_NUM_SPI]; + +static const struct ao_spi_stm_slave_info ao_spi_stm_slave_info[STM_NUM_SPI] = { +	{ +		.miso_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_RX), +		.mosi_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_TX), +		&stm_spi1 +	}, +	{ +		.miso_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_RX), +		.mosi_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_TX), +		&stm_spi2 +	} +}; + +static uint8_t	spi_dev_null; + +void +ao_spi_slave_send(void *block, uint16_t len) +{ +	struct stm_spi *stm_spi = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].miso_dma_index; + +	/* Set up the transmit DMA to deliver data */ +	ao_dma_set_transfer(mosi_dma_index, +			    &stm_spi->dr, +			    block, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (1 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); + +	/* Clear RXNE */ +	(void) stm_spi->dr; + +	/* Set up the receive DMA -- when this is done, we know the SPI unit +	 * is idle. Without this, we'd have to poll waiting for the BSY bit to +	 * be cleared +	 */ +	ao_dma_set_transfer(miso_dma_index, +			    &stm_spi->dr, +			    &spi_dev_null, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (0 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); +	stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | +			(0 << STM_SPI_CR2_RXNEIE) | +			(0 << STM_SPI_CR2_ERRIE) | +			(0 << STM_SPI_CR2_SSOE) | +			(1 << STM_SPI_CR2_TXDMAEN) | +			(1 << STM_SPI_CR2_RXDMAEN)); +	ao_dma_start(miso_dma_index); +	ao_dma_start(mosi_dma_index); +	ao_arch_critical( +		while (!ao_dma_done[miso_dma_index]) +			ao_sleep(&ao_dma_done[miso_dma_index]); +		); +	ao_dma_done_transfer(mosi_dma_index); +	ao_dma_done_transfer(miso_dma_index); +} + + +uint8_t +ao_spi_slave_recv(void *block, uint16_t len) +{ +	struct stm_spi *stm_spi = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].miso_dma_index; + +	/* Set up transmit DMA to make the SPI hardware actually run */ +	ao_dma_set_transfer(mosi_dma_index, +			    &stm_spi->dr, +			    &spi_dev_null, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (0 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); + +	/* Clear RXNE */ +	(void) stm_spi->dr; + +	/* Set up the receive DMA to capture data */ +	ao_dma_set_transfer(miso_dma_index, +			    &stm_spi->dr, +			    block, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (1 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); + +	stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | +			(0 << STM_SPI_CR2_RXNEIE) | +			(0 << STM_SPI_CR2_ERRIE) | +			(0 << STM_SPI_CR2_SSOE) | +			(1 << STM_SPI_CR2_TXDMAEN) | +			(1 << STM_SPI_CR2_RXDMAEN)); +	ao_dma_start(miso_dma_index); +	ao_dma_start(mosi_dma_index); + +	/* Wait until the SPI unit is done */ +	ao_arch_critical( +		while (!ao_dma_done[miso_dma_index]) +			ao_sleep(&ao_dma_done[miso_dma_index]); +		); + +	ao_dma_done_transfer(mosi_dma_index); +	ao_dma_done_transfer(miso_dma_index); +} + +static void +ao_spi_slave_disable_index(uint8_t spi_index) +{ +	/* Disable current config +	 */ +	switch (AO_SPI_INDEX(spi_index)) { +	case STM_SPI_INDEX(1): +		switch (spi_index) { +		case AO_SPI_1_PA5_PA6_PA7: +			stm_gpio_set(&stm_gpioa, 5, 1); +			stm_moder_set(&stm_gpioa, 5, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpioa, 6, STM_MODER_INPUT); +			stm_moder_set(&stm_gpioa, 7, STM_MODER_OUTPUT); +			break; +		case AO_SPI_1_PB3_PB4_PB5: +			stm_gpio_set(&stm_gpiob, 3, 1); +			stm_moder_set(&stm_gpiob, 3, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpiob, 4, STM_MODER_INPUT); +			stm_moder_set(&stm_gpiob, 5, STM_MODER_OUTPUT); +			break; +		case AO_SPI_1_PE13_PE14_PE15: +			stm_gpio_set(&stm_gpioe, 13, 1); +			stm_moder_set(&stm_gpioe, 13, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpioe, 14, STM_MODER_INPUT); +			stm_moder_set(&stm_gpioe, 15, STM_MODER_OUTPUT); +			break; +		} +		break; +	case STM_SPI_INDEX(2): +		switch (spi_index) { +		case AO_SPI_2_PB13_PB14_PB15: +			stm_gpio_set(&stm_gpiob, 13, 1); +			stm_moder_set(&stm_gpiob, 13, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpiob, 14, STM_MODER_INPUT); +			stm_moder_set(&stm_gpiob, 15, STM_MODER_OUTPUT); +			break; +		case AO_SPI_2_PD1_PD3_PD4: +			stm_gpio_set(&stm_gpiod, 1, 1); +			stm_moder_set(&stm_gpiod, 1, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpiod, 3, STM_MODER_INPUT); +			stm_moder_set(&stm_gpiod, 4, STM_MODER_OUTPUT); +			break; +		} +		break; +	} +} + +static void +ao_spi_slave_enable_index(uint8_t spi_index) +{ +	switch (AO_SPI_INDEX(spi_index)) { +	case STM_SPI_INDEX(1): +		switch (spi_index) { +		case AO_SPI_1_PA5_PA6_PA7: +			stm_afr_set(&stm_gpioa, 5, STM_AFR_AF5); +			stm_afr_set(&stm_gpioa, 6, STM_AFR_AF5); +			stm_afr_set(&stm_gpioa, 7, STM_AFR_AF5); +			break; +		case AO_SPI_1_PB3_PB4_PB5: +			stm_afr_set(&stm_gpiob, 3, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 4, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 5, STM_AFR_AF5); +			break; +		case AO_SPI_1_PE13_PE14_PE15: +			stm_afr_set(&stm_gpioe, 13, STM_AFR_AF5); +			stm_afr_set(&stm_gpioe, 14, STM_AFR_AF5); +			stm_afr_set(&stm_gpioe, 15, STM_AFR_AF5); +			break; +		} +		break; +	case STM_SPI_INDEX(2): +		switch (spi_index) { +		case AO_SPI_2_PB13_PB14_PB15: +			stm_afr_set(&stm_gpiob, 13, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 14, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); +			break; +		case AO_SPI_2_PD1_PD3_PD4: +			stm_afr_set(&stm_gpiod, 1, STM_AFR_AF5); +			stm_afr_set(&stm_gpiod, 3, STM_AFR_AF5); +			stm_afr_set(&stm_gpiod, 4, STM_AFR_AF5); +			break; +		} +		break; +	} +} + +void +ao_spi_slave_get(uint8_t spi_index, uint32_t speed) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_slave_info[id].stm_spi; + +	ao_mutex_get(&ao_spi_slave_mutex[id]); +	stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) |			/* Three wire mode */ +			(0 << STM_SPI_CR1_BIDIOE) | +			(0 << STM_SPI_CR1_CRCEN) |			/* CRC disabled */ +			(0 << STM_SPI_CR1_CRCNEXT) | +			(0 << STM_SPI_CR1_DFF) | +			(0 << STM_SPI_CR1_RXONLY) | +			(1 << STM_SPI_CR1_SSM) |        		/* Software SS handling */ +			(1 << STM_SPI_CR1_SSI) |			/*  ... */ +			(0 << STM_SPI_CR1_LSBFIRST) |			/* Big endian */ +			(1 << STM_SPI_CR1_SPE) |			/* Enable SPI unit */ +			(speed << STM_SPI_CR1_BR) |	/* baud rate to pclk/4 */ +			(1 << STM_SPI_CR1_MSTR) | +			(0 << STM_SPI_CR1_CPOL) |			/* Format 0 */ +			(0 << STM_SPI_CR1_CPHA)); +	if (spi_index != ao_spi_slave_index[id]) { +		 +		/* Disable old config +		 */ +		ao_spi_slave_disable_index(ao_spi_slave_index[id]); + +		/* Enable new config +		 */ +		ao_spi_slave_enable_index(spi_index); +		 +		/* Remember current config +		 */ +		ao_spi_slave_index[id] = spi_index; +	} +} + +void +ao_spi_slave_put(uint8_t spi_index) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_slave_info[id].stm_spi; + +	stm_spi->cr1 = 0; +	ao_mutex_put(&ao_spi_slave_mutex[id]); +} + +static void +ao_spi_channel_init(uint8_t spi_index) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_slave_info[id].stm_spi; + +	ao_spi_slave_disable_index(spi_index); + +	stm_spi->cr1 = 0; +	(void) stm_spi->sr; +	stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | +			(0 << STM_SPI_CR2_RXNEIE) | +			(0 << STM_SPI_CR2_ERRIE) | +			(0 << STM_SPI_CR2_SSOE) | +			(0 << STM_SPI_CR2_TXDMAEN) | +			(0 << STM_SPI_CR2_RXDMAEN)); +} + +void +ao_spi_slave_init(void) +{ +#if HAS_SPI_SLAVE_1 +# if SPI_1_PA5_PA6_PA7 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); +# endif +# if SPI_1_PB3_PB4_PB5 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +# endif +# if SPI_1_PE13_PE14_PE15 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); +# endif +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN); +	ao_spi_slave_index[0] = AO_SPI_CONFIG_NONE; +	ao_spi_channel_init(0); +#endif + +#if HAS_SPI_SLAVE_2 +# if SPI_2_PB13_PB14_PB15 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +# endif +# if SPI_2_PD1_PD3_PD4 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); +# endif +	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); +	ao_spi_slave_index[1] = AO_SPI_CONFIG_NONE; +	ao_spi_channel_init(1); +#endif +} diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 0dbfae39..1d636037 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -811,30 +811,41 @@ extern struct stm_lcd stm_lcd;  #define STM_LCD_CLR_UDDC		(3)  #define STM_LCD_CLR_SOFC		(1) +/* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */ +  struct stm_nvic { -	vuint32_t	iser[3];	/* 0x000 */ +	vuint32_t	iser[8];	/* 0x000 0xe000e100 Set Enable Register */ + +	uint8_t		_unused020[0x080 - 0x020]; + +	vuint32_t	icer[8];	/* 0x080 0xe000e180 Clear Enable Register */ -	uint8_t		_unused00c[0x080 - 0x00c]; +	uint8_t		_unused0a0[0x100 - 0x0a0]; -	vuint32_t	icer[3];	/* 0x080 */ +	vuint32_t	ispr[8];	/* 0x100 0xe000e200 Set Pending Register */ -	uint8_t		_unused08c[0x100 - 0x08c]; +	uint8_t		_unused120[0x180 - 0x120]; -	vuint32_t	ispr[3];	/* 0x100 */ +	vuint32_t	icpr[8];	/* 0x180 0xe000e280 Clear Pending Register */ -	uint8_t		_unused10c[0x180 - 0x10c]; +	uint8_t		_unused1a0[0x200 - 0x1a0]; -	vuint32_t	icpr[3];	/* 0x180 */ +	vuint32_t	iabr[8];	/* 0x200 0xe000e300 Active Bit Register */ -	uint8_t		_unused18c[0x200 - 0x18c]; +	uint8_t		_unused220[0x300 - 0x220]; -	vuint32_t	iabr[3];	/* 0x200 */ +	vuint32_t	ipr[60];	/* 0x300 0xe000e400 Priority Register */ -	uint8_t		_unused20c[0x300 - 0x20c]; +	uint8_t		_unused3f0[0xc00 - 0x3f0]; -	vuint32_t	ipr[21];	/* 0x300 */ +	vuint32_t	cpuid_base;	/* 0xc00 0xe000ed00 CPUID Base Register */ +	vuint32_t	ics;		/* 0xc04 0xe000ed04 Interrupt Control State Register */ +	vuint32_t	vto;		/* 0xc08 0xe000ed08 Vector Table Offset Register */ +	vuint32_t	ai_rc;		/* 0xc0c 0xe000ed0c Application Interrupt/Reset Control Register */ +	vuint32_t	sc;		/* 0xc10 0xe000ed10 System Control Register */ +	vuint32_t	cc;		/* 0xc14 0xe000ed14 Configuration Control Register */ -	uint8_t		_unused324[0xe00 - 0x324]; +	uint8_t		_unusedc18[0xe00 - 0xc18];  	vuint32_t	stir;		/* 0xe00 */  }; diff --git a/src/telelco-v0.1/ao_pins.h b/src/telelco-v0.1/ao_pins.h index 60cf018f..970f9bd1 100644 --- a/src/telelco-v0.1/ao_pins.h +++ b/src/telelco-v0.1/ao_pins.h @@ -49,18 +49,19 @@  #define HAS_TELEMETRY		0  #define HAS_AES			1 -#define HAS_SPI_1		1 -#define SPI_1_PA5_PA6_PA7	1 +#define HAS_SPI_1		0 +#define SPI_1_PA5_PA6_PA7	0  #define SPI_1_PB3_PB4_PB5	0  #define SPI_1_PE13_PE14_PE15	0 -#define HAS_SPI_2		1 +#define HAS_SPI_2		1	/* CC1111 */  #define SPI_2_PB13_PB14_PB15	1  #define SPI_2_PD1_PD3_PD4	0  #define SPI_2_GPIO		(&stm_gpiob)  #define SPI_2_SCK		13  #define SPI_2_MISO		14  #define SPI_2_MOSI		15 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz  #define HAS_I2C_1		0 diff --git a/src/telescience-v0.2/.gitignore b/src/telescience-v0.2/.gitignore new file mode 100644 index 00000000..cc1f8b73 --- /dev/null +++ b/src/telescience-v0.2/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telescience-*.elf diff --git a/src/telescience-v0.2/Makefile b/src/telescience-v0.2/Makefile new file mode 100644 index 00000000..fbeeb75c --- /dev/null +++ b/src/telescience-v0.2/Makefile @@ -0,0 +1,85 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ +	ao.h \ +	ao_arch.h \ +	ao_arch_funcs.h \ +	ao_pins.h \ +	ao_product.h \ +	ao_cc1120_CC1120.h \ +	ao_task.h \ +	ao_whiten.h \ +	stm32l.h \ +	Makefile + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +#	ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +ALTOS_SRC = \ +	ao_interrupt.c \ +	ao_product.c \ +	ao_romconfig.c \ +	ao_cmd.c \ +	ao_config.c \ +	ao_task.c \ +	ao_led.c \ +	ao_stdio.c \ +	ao_panic.c \ +	ao_timer.c \ +	ao_mutex.c \ +	ao_dma_stm.c \ +	ao_spi_stm.c \ +	ao_usb_stm.c \ +	ao_adc_stm.c \ +	ao_data.c \ +	ao_exti_stm.c \ +	ao_storage.c \ +	ao_m25.c \ +	ao_science_slave.c \ +	ao_spi_stm_slave.c \ +	ao_log_telescience.c \ +	ao_log_single.c + +PRODUCT=TeleScience-v0.2 +PRODUCT_DEF=-DTELESCIENCE +IDPRODUCT=0x0011 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telescience-v0.2 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telescience.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +$(PROG): Makefile $(OBJ) altos.ld +	$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version +	$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean:	clean + +clean: +	rm -f *.o $(PROGNAME)-*.elf +	rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telescience-v0.2/ao_pins.h b/src/telescience-v0.2/ao_pins.h new file mode 100644 index 00000000..7b974506 --- /dev/null +++ b/src/telescience-v0.2/ao_pins.h @@ -0,0 +1,144 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_TASK_QUEUE		1 + +/* 8MHz High speed external crystal */ +#define AO_HSE			8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL		12 +#define AO_RCC_CFGR_PLLMUL	(STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV		3 +#define AO_RCC_CFGR_PLLDIV	(STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER	1 +#define AO_RCC_CFGR_HPRE_DIV	STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER	2 +#define AO_RCC_CFGR_PPRE1_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER	2 +#define AO_RCC_CFGR_PPRE2_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1		0 +#define USE_SERIAL_1_STDIN	0 +#define SERIAL_1_PB6_PB7	0 +#define SERIAL_1_PA9_PA10	1 + +#define HAS_SERIAL_2		0 +#define USE_SERIAL_2_STDIN	0 +#define SERIAL_2_PA2_PA3	0 +#define SERIAL_2_PD5_PD6	0 + +#define HAS_SERIAL_3		0 +#define USE_SERIAL_3_STDIN	0 +#define SERIAL_3_PB10_PB11	0 +#define SERIAL_3_PC10_PC11	1 +#define SERIAL_3_PD8_PD9	0 + +#define HAS_EEPROM		1 +#define USE_INTERNAL_FLASH	0 +#define HAS_USB			1 +#define HAS_BEEP		0 +#define HAS_RADIO		0 +#define HAS_TELEMETRY		0 +#define PACKET_HAS_SLAVE	0 + +#define HAS_SPI_1		0 +#define HAS_SPI_SLAVE_1		1 +#define SPI_1_PA5_PA6_PA7	1	 +#define SPI_1_PB3_PB4_PB5	0 +#define SPI_1_PE13_PE14_PE15	0 +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz + +#define HAS_SPI_2		1 +#define SPI_2_PB13_PB14_PB15	1 +#define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz + +#define SPI_2_PORT		(&stm_gpiob) +#define SPI_2_SCK_PIN		13 +#define SPI_2_MISO_PIN		14 +#define SPI_2_MOSI_PIN		15 +#define SPI_SLAVE_INDEX		1 + +#define HAS_I2C_1		0 +#define I2C_1_PB8_PB9		0 + +#define HAS_I2C_2		0 +#define I2C_2_PB10_PB11		0 + +#define LOW_LEVEL_DEBUG		0 + +#define LED_PORT_0_ENABLE	STM_RCC_AHBENR_GPIOAEN + +#define LED_PORT_0		(&stm_gpioa) +#define LED_PORT_0_MASK		(0xff) +#define LED_PORT_0_SHIFT	0 +#define LED_PIN_RED		8 +#define LED_PIN_GREEN		9 +#define AO_LED_RED		(1 << LED_PIN_RED) +#define AO_LED_GREEN		(1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE		(AO_LED_RED | AO_LED_GREEN) + +#define HAS_GPS			0 +#define HAS_FLIGHT		0 +#define HAS_ADC			1 +#define HAS_LOG			1 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS		1 +#define AO_M25_SPI_CS_PORT	(&stm_gpioa) +#define AO_M25_SPI_CS_MASK	(1 << 3) +#define AO_M25_SPI_BUS		AO_SPI_2_PB13_PB14_PB15 + +/* + * ADC + */ + +#define AO_DATA_RING		32 +#define AO_ADC_NUM		1 + +struct ao_adc { +	int16_t			adc[AO_ADC_NUM]; +}; + +#define AO_ADC_TEMP		16 + +#define AO_ADC_RCC_AHBENR	0 + +#define AO_NUM_ADC_PIN		0 + +#define AO_NUM_ADC	       	1 + +#define AO_ADC_SQ1		AO_ADC_TEMP + + +#endif /* _AO_PINS_H_ */ diff --git a/src/telescience-v0.2/ao_telescience.c b/src/telescience-v0.2/ao_telescience.c new file mode 100644 index 00000000..2fb3186a --- /dev/null +++ b/src/telescience-v0.2/ao_telescience.c @@ -0,0 +1,51 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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_exti.h> +#include <ao_packet.h> +#include <ao_send_packet.h> + +int +main(void) +{ +	ao_clock_init(); +	 +#if HAS_STACK_GUARD +	ao_mpu_init(); +#endif + +	ao_task_init(); +	ao_led_init(LEDS_AVAILABLE); +	ao_led_on(AO_LED_GREEN); +	ao_timer_init(); + +	ao_spi_init(); +	ao_spi_slave_init(); +	ao_dma_init(); +	ao_exti_init(); + +	ao_cmd_init(); + +	ao_usb_init(); +	ao_config_init(); +	 +	ao_storage_init(); + +	ao_start_scheduler(); +	return 0; +} | 
