Merge remote-tracking branch 'mjb/master'
authorKeith Packard <keithp@keithp.com>
Thu, 7 Mar 2013 05:53:22 +0000 (21:53 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 7 Mar 2013 05:53:22 +0000 (21:53 -0800)
34 files changed:
altoslib/AltosState.java
altosuilib/AltosUIGraph.java
altosuilib/AltosUIGrapher.java
altosuilib/AltosUIMarker.java
ao-tools/Makefile.am
ao-tools/ao-dumpflash/.gitignore [new file with mode: 0644]
ao-tools/ao-dumpflash/Makefile.am [new file with mode: 0644]
ao-tools/ao-dumpflash/ao-dumpflash.1 [new file with mode: 0644]
ao-tools/ao-dumpflash/ao-dumpflash.c [new file with mode: 0644]
ao-tools/lib/cc-usb.c
ao-tools/lib/cc-usb.h
ao-tools/lib/ccdbg-flash.c
configure.ac
doc/Makefile
doc/altusmetrum.xsl
doc/release-notes-1.2.xsl [new file with mode: 0644]
libaltos/libaltos.c
src/Makefile
src/avr/ao_spi_slave.c
src/core/ao.h
src/drivers/ao_cc1120.c
src/drivers/ao_hmc5883.c
src/megadongle-v0.1/ao_pins.h
src/megametrum-v0.1/ao_pins.h
src/stm-demo/ao_pins.h
src/stm/ao_arch_funcs.h
src/stm/ao_spi_stm.c
src/stm/ao_spi_stm_slave.c [new file with mode: 0644]
src/stm/stm32l.h
src/telelco-v0.1/ao_pins.h
src/telescience-v0.2/.gitignore [new file with mode: 0644]
src/telescience-v0.2/Makefile [new file with mode: 0644]
src/telescience-v0.2/ao_pins.h [new file with mode: 0644]
src/telescience-v0.2/ao_telescience.c [new file with mode: 0644]

index 32d02f21d1923ba934cb756e7d013196aac3ec6d..5598a60353b9af204dd78634de0200c25d7eeb1c 100644 (file)
@@ -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;
index 5c589c02555070637c7d3055cb9c91087f70c848..5f3a2eef30a8064936f4abc763160cd4298124e6 100644 (file)
@@ -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) {
index c627fec52bd37cbe3833b8ade2daba5b8d9a6add..8f0ce8011d6595d7812d9b9888cfd8f2f7cc3fb1 100644 (file)
@@ -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();
 }
index e2eb9028d147892b9d6a70794ff9dd0cb0bdee14..0949be6f94af3122ed0b31d2643eb16754b40c9f 100644 (file)
@@ -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);
        }
index 871b8205705757aa1b86f1045474316435bfc993..139eea3f18b1665d00afda69f46b4fd5e169726c 100644 (file)
@@ -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 (file)
index 0000000..bbce511
--- /dev/null
@@ -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 (file)
index 0000000..db99f5a
--- /dev/null
@@ -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 (file)
index 0000000..07a08ba
--- /dev/null
@@ -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 (file)
index 0000000..3cd21e6
--- /dev/null
@@ -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);
+}
index 1580c6d9ffee488f84e1910e3e1cc9ecec943938..9f07e6624d2c849f7469c07cbc80dc018648f383 100644 (file)
@@ -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);
index d3539281f83aa4001c22a696a8eb15c90e69160f..e90e1195b100f34a5858bb8b6e2500609e66fe95 100644 (file)
@@ -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);
index 3e6729851502ff8895a6e2088836284035f7702c..1b46870b86d96de483ea59b72be2443eb1ddb39d 100644 (file)
@@ -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);
index a1c8c4fc66b74c3aa89fd9d0e565674b63899631..9e5dcaa7e23239dafdbef2c4cf44f6b7a254cac7 100644 (file)
@@ -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,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
 ])
index 59fd4ebb1f153eff6abf679b4e4e53feef193684..7c4da29ecf1c96df4ee5e87ad207e666b2271ff5 100644 (file)
@@ -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)
index 9fdd6b07ef098fde375df9f9f415821500a412aa..c5c08d4e0e1a78073361210bc49ddb135823c2c6 100644 (file)
@@ -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 (file)
index 0000000..610fa1a
--- /dev/null
@@ -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>
index ca56746a643d8cd0de773ceb180e0c2ea95320b3..2a41ef80159e1813f7573672fe049a69d1c78a65 100644 (file)
@@ -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;
index 67ad97d1b7e54500ad153b467f73723b4fc6357b..9e31e3ea914eb9e587310f17bc0072f95d001101 100644 (file)
@@ -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)
index a400b8a0a929f0485b8d8da894f43c17ec098f79..15e9924da5d6f20c4b1b454a3393d3fea9d23c31 100644 (file)
 #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;
index df5bbf487e2469702421b27a25d7ac9378351d03..ce0bf5d14289007dff1b602e750cdc7b23dec7f4 100644 (file)
@@ -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);
index 8068740f91782483e6f83329a4f439d2c778b5a5..53bb5a62f5621bedb4c94d48d76b660b5213ea46 100644 (file)
@@ -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)
index 059fc2c8d5fb85d75872d9325e34f341f50a5991..782d03f447e7a79a619b0e79b4814c0fcb4c9ae2 100644 (file)
@@ -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) |
index c766a48c6d24b46d91fb698a6d4bb0d6a309042c..d460a49095b9a38fdd3fd93cb05cdbf122f91f37 100644 (file)
@@ -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
index 64da41a915304f618b6aa0547969701d0dcd2b55..4c645871fe758d6f6159da4aa49e38ef2823e936 100644 (file)
 #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
index c9c7446e4e21d489aa1ff80fe25a9c2e1fce3779..07b4a19d919a78c989bd2d48bc53307809cdd463 100644 (file)
@@ -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
 
index 87bbe73e3b926a6b964d181f6dc5a60926cb4305..d17793076f38ca177e60f66082288c607044d1b5 100644 (file)
@@ -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 */
 
index 599d7ee09981694ac4dabea3e695028ec30718be..7b4af96443f28af949669e2d1cf18c2a49d2db49 100644 (file)
@@ -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 (file)
index 0000000..9802244
--- /dev/null
@@ -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
+}
index 0dbfae39814c0fd4a5e43805bbbe66c120800ce9..1d6360372e9a51c604bc059b88b8961f27ffc4fb 100644 (file)
@@ -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 */
 };
index 60cf018f4f315e0efc1e06ce52e01ef8a91734e4..970f9bd1799d678060a79ff40ae347c262801b8f 100644 (file)
 #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 (file)
index 0000000..cc1f8b7
--- /dev/null
@@ -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 (file)
index 0000000..fbeeb75
--- /dev/null
@@ -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 (file)
index 0000000..7b97450
--- /dev/null
@@ -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 (file)
index 0000000..2fb3186
--- /dev/null
@@ -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;
+}