From: Bdale Garbee Date: Sat, 6 Dec 2014 22:39:53 +0000 (-0700) Subject: Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos X-Git-Tag: bdale-altosdroid~6 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=7339d2379713b5b7e4c4fe6bad89ed93f9d39e82;hp=d1f9121593fe30b924223e89ef4d596b5bec2b25 Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos --- diff --git a/altosdroid/release-note-1.5 b/altosdroid/release-note-1.5 new file mode 100644 index 00000000..98f88d98 --- /dev/null +++ b/altosdroid/release-note-1.5 @@ -0,0 +1,7 @@ +Version 1.5 + + * TeleGPS support + * Reloads previous flight data at startup + * Fixes crash when touching map + * Reconnect to TeleBT at startup + * Remember radio settings diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index f6cceac9..e883322c 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -337,7 +337,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener { } if (saved_state == null || state.flight != saved_state.flight) { Log.d(TAG, "update flight"); - mFlightView.setText(String.format("%d", state.flight)); + if (state.flight == AltosLib.MISSING) + mFlightView.setText(""); + else + mFlightView.setText(String.format("%d", state.flight)); } if (saved_state == null || state.state != saved_state.state) { Log.d(TAG, "update state"); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java index be41ae7c..09a2a7a2 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java @@ -22,6 +22,7 @@ import java.util.Map; import android.content.Context; import android.content.SharedPreferences; import android.os.Environment; +import android.util.*; import org.altusmetrum.altoslib_5.*; @@ -71,6 +72,16 @@ public class AltosDroidPreferencesBackend implements AltosPreferencesBackend { return prefs.getString(key, def); } + public byte[] getBytes(String key, byte[] def) { + String save = prefs.getString(key, null); + + if (save == null) + return def; + + byte[] bytes = Base64.decode(save, Base64.DEFAULT); + return bytes; + } + public void putBoolean(String key, boolean value) { editor.putBoolean(key, value); } @@ -87,6 +98,11 @@ public class AltosDroidPreferencesBackend implements AltosPreferencesBackend { editor.putString(key, value); } + public void putBytes(String key, byte[] bytes) { + String save = Base64.encodeToString(bytes, Base64.DEFAULT); + editor.putString(key, save); + } + public void remove(String key) { editor.remove(key); } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java index fa4e3c8b..2c406339 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java @@ -101,7 +101,7 @@ public class TabAscent extends AltosDroidTab { if (state.gps != null) { mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S")); - mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E")); + mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "E", "W")); } else { mLatitudeView.setText(""); mLongitudeView.setText(""); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java index 28068666..cc5b2183 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java @@ -110,7 +110,7 @@ public class TabDescent extends AltosDroidTab { } if (state.gps != null) { mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S")); - mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E")); + mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "E", "W")); } mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.apogee_voltage)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java index b257b936..013be0cd 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java @@ -82,12 +82,12 @@ public class TabLanded extends AltosDroidTab { } if (state != null && state.gps != null) { mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S")); - mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E")); + mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "E", "W")); } if (receiver != null) { mReceiverLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S")); - mReceiverLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E")); + mReceiverLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "E", "W")); } if (state != null) { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java index ab338ac2..a625aa19 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java @@ -179,7 +179,7 @@ public class TabMap extends AltosDroidTab { } if (state.gps != null) { mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S")); - mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E")); + mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "E", "W")); if (state.gps.locked && state.gps.nsat >= 4) center (state.gps.lat, state.gps.lon, 10); } @@ -193,9 +193,12 @@ public class TabMap extends AltosDroidTab { else accuracy = 1000; mReceiverLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S")); - mReceiverLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E")); + mReceiverLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "E", "W")); center (receiver.getLatitude(), receiver.getLongitude(), accuracy); } } + + public TabMap() { + } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java index 32df71d7..c8e2ed64 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java @@ -163,7 +163,7 @@ public class TabPad extends AltosDroidTab { if (receiver.hasAltitude()) altitude = receiver.getAltitude(); mPadLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S")); - mPadLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E")); + mPadLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "E", "W")); set_value(mPadAltitudeView, AltosConvert.height, 6, altitude); } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java index 971c3e80..03abeec6 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -40,8 +40,6 @@ public class TelemetryReader extends Thread { AltosLink link; AltosState state = null; - AltosFlightReader stacked; - LinkedBlockingQueue telemQueue; public AltosState read() throws ParseException, AltosCRCException, InterruptedException, IOException { @@ -59,10 +57,6 @@ public class TelemetryReader extends Thread { public void close() { state = null; - if (stacked != null) { - stacked.close(false); - stacked = null; - } link.remove_monitor(telemQueue); link = null; telemQueue.clear(); @@ -73,25 +67,6 @@ public class TelemetryReader extends Thread { AltosState state = null; try { - if (D) Log.d(TAG, "starting reader"); - while (stacked != null) { - AltosState stacked_state = null; - try { - stacked_state = stacked.read(); - } catch (ParseException pe) { - continue; - } catch (AltosCRCException ce) { - continue; - } - if (stacked_state != null) - state = stacked_state; - else - stacked = null; - } - if (state != null) { - if (D) Log.d(TAG, "Send initial state"); - handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget(); - } if (D) Log.d(TAG, "starting loop"); while (telemQueue != null) { try { @@ -111,34 +86,16 @@ public class TelemetryReader extends Thread { } } - public TelemetryReader (AltosLink in_link, Handler in_handler, AltosFlightReader in_stacked) { + public TelemetryReader (AltosLink in_link, Handler in_handler, AltosState in_state) { if (D) Log.d(TAG, "connected TelemetryReader create started"); link = in_link; handler = in_handler; - stacked = in_stacked; - state = null; + state = in_state; telemQueue = new LinkedBlockingQueue(); link.add_monitor(telemQueue); link.set_telemetry(AltosLib.ao_telemetry_standard); if (D) Log.d(TAG, "connected TelemetryReader created"); } - - private static AltosFlightReader existing_data(AltosLink link) { - if (link == null) - return null; - - File file = AltosPreferences.logfile(link.serial); - if (file != null) { - AltosStateIterable iterable = AltosStateIterable.iterable(file); - if (iterable != null) - return new AltosReplayReader(iterable.iterator(), file, false); - } - return null; - } - - public TelemetryReader(AltosLink link, Handler handler) { - this(link, handler, existing_data(link)); - } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 30d94409..e029c75c 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -139,6 +139,10 @@ public class TelemetryService extends Service implements LocationListener { case MSG_TELEMETRY: // forward telemetry messages s.telemetry_state.state = (AltosState) msg.obj; + if (s.telemetry_state.state != null) { + if (D) Log.d(TAG, "Save state"); + AltosPreferences.set_state(0, s.telemetry_state.state, null); + } if (D) Log.d(TAG, "MSG_TELEMETRY"); s.sendMessageToClients(); break; @@ -179,6 +183,8 @@ public class TelemetryService extends Service implements LocationListener { private Message message() { if (telemetry_state == null) Log.d(TAG, "telemetry_state null!"); + if (telemetry_state.state == null) + Log.d(TAG, "telemetry_state.state null!"); return Message.obtain(null, AltosDroid.MSG_STATE, telemetry_state); } @@ -262,7 +268,7 @@ public class TelemetryService extends Service implements LocationListener { if (D) Log.d(TAG, "connected bluetooth configured"); telemetry_state.connect = TelemetryState.CONNECT_CONNECTED; - mTelemetryReader = new TelemetryReader(mAltosBluetooth, mHandler); + mTelemetryReader = new TelemetryReader(mAltosBluetooth, mHandler, telemetry_state.state); mTelemetryReader.start(); if (D) Log.d(TAG, "connected TelemetryReader started"); @@ -306,6 +312,13 @@ public class TelemetryService extends Service implements LocationListener { telemetry_state.connect = TelemetryState.CONNECT_READY; + AltosSavedState saved_state = AltosPreferences.state(0); + + if (saved_state != null) { + if (D) Log.d(TAG, String.format("recovered old state flight %d\n", saved_state.state.flight)); + telemetry_state.state = saved_state.state; + } + // Start our timer - first event in 10 seconds, then every 10 seconds after that. timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 10000L, 10000L); diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index d91da4da..e40a47b4 100644 --- a/altoslib/AltosAccel.java +++ b/altoslib/AltosAccel.java @@ -17,7 +17,9 @@ package org.altusmetrum.altoslib_5; -public class AltosAccel extends AltosUnits { +import java.io.*; + +public class AltosAccel extends AltosUnits implements Serializable { public double value(double v, boolean imperial_units) { if (imperial_units) @@ -46,4 +48,4 @@ public class AltosAccel extends AltosUnits { public int show_fraction(int width, boolean imperial_units) { return width / 9; } -} \ No newline at end of file +} diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 2357dbc7..2ad50097 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -158,7 +158,7 @@ public class AltosCSV implements AltosWriter { } void write_advanced_header() { - out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z"); + out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z"); } void write_advanced(AltosState state) { diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java index 47deb2a3..7e9ab2f1 100644 --- a/altoslib/AltosCompanion.java +++ b/altoslib/AltosCompanion.java @@ -17,7 +17,9 @@ package org.altusmetrum.altoslib_5; -public class AltosCompanion { +import java.io.*; + +public class AltosCompanion implements Serializable { public final static int board_id_telescience = 0x0a; public final static int MAX_CHANNELS = 12; diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 0154e95d..285b5b45 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -19,8 +19,9 @@ package org.altusmetrum.altoslib_5; import java.text.*; import java.util.concurrent.*; +import java.io.*; -public class AltosGPS implements Cloneable { +public class AltosGPS implements Cloneable, Serializable { public final static int MISSING = AltosLib.MISSING; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index 716eeef9..22a8e0e5 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -18,8 +18,9 @@ package org.altusmetrum.altoslib_5; import java.lang.Math; +import java.io.*; -public class AltosGreatCircle implements Cloneable { +public class AltosGreatCircle implements Cloneable, Serializable { public double distance; public double bearing; public double range; diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index d7373f3c..02b458b8 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -18,8 +18,9 @@ package org.altusmetrum.altoslib_5; import java.util.concurrent.*; +import java.io.*; -public class AltosIMU implements Cloneable { +public class AltosIMU implements Cloneable, Serializable { public int accel_along; public int accel_across; public int accel_through; diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index 85bcff10..57c77c47 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -35,20 +35,6 @@ public class AltosIdleMonitor extends Thread { AltosConfigData config_data; AltosGPS gps; - int AltosRSSI() throws TimeoutException, InterruptedException { - link.printf("s\n"); - String line = link.get_reply_no_dialog(5000); - if (line == null) - throw new TimeoutException(); - String[] items = line.split("\\s+"); - if (items.length < 2) - return 0; - if (!items[0].equals("RSSI:")) - return 0; - int rssi = Integer.parseInt(items[1]); - return rssi; - } - void start_link() throws InterruptedException, TimeoutException { if (remote) { link.set_radio_frequency(frequency); @@ -58,26 +44,30 @@ public class AltosIdleMonitor extends Thread { link.flush_input(); } - void stop_link() throws InterruptedException, TimeoutException { + boolean stop_link() throws InterruptedException, TimeoutException { if (remote) link.stop_remote(); + return link.reply_abort; } - void update_state(AltosState state) throws InterruptedException, TimeoutException { + boolean update_state(AltosState state) throws InterruptedException, TimeoutException { boolean worked = false; + boolean aborted = false; try { start_link(); fetch.update_state(state); - worked = true; + if (!link.has_error && !link.reply_abort) + worked = true; } finally { - stop_link(); + aborted = stop_link(); if (worked) { if (remote) state.set_rssi(link.rssi(), 0); listener_state.battery = link.monitor_battery(); } } + return aborted; } public void set_frequency(double in_frequency) { @@ -102,13 +92,17 @@ public class AltosIdleMonitor extends Thread { public void run() { AltosState state = new AltosState(); try { - while (!link.has_error) { + for (;;) { try { link.config_data(); update_state(state); listener.update(state, listener_state); } catch (TimeoutException te) { } + if (link.has_error || link.reply_abort) { + listener.failed(); + break; + } Thread.sleep(1000); } } catch (InterruptedException ie) { diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java index 4382430c..36484763 100644 --- a/altoslib/AltosIdleMonitorListener.java +++ b/altoslib/AltosIdleMonitorListener.java @@ -19,4 +19,5 @@ package org.altusmetrum.altoslib_5; public interface AltosIdleMonitorListener { public void update(AltosState state, AltosListenerState listener_state); -} \ No newline at end of file + public void failed(); +} diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 0edc0b43..be69519b 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -188,6 +188,7 @@ public class AltosLib { }; public static final String launch_sites_url = "http://www.altusmetrum.org/AltOS/launch-sites.txt"; +// public static final String launch_sites_url = "file:///home/keithp/misc/text/altusmetrum/AltOS/launch-sites.txt"; public static final int ao_telemetry_standard_len = 32; public static final int ao_telemetry_0_9_len = 95; diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 62bd82b9..639d2ac7 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -55,8 +55,11 @@ public abstract class AltosLink implements Runnable { public void printf(String format, Object ... arguments) { String line = String.format(format, arguments); - if (debug) - pending_output.add(line); + if (debug) { + synchronized (pending_output) { + pending_output.add(line); + } + } try { print(line); } catch (InterruptedException ie) { @@ -286,12 +289,14 @@ public abstract class AltosLink implements Runnable { binary_queue.put(dup); } - public void flush_output() { + public synchronized void flush_output() { if (pending_output == null) return; - for (String s : pending_output) - System.out.print(s); - pending_output.clear(); + synchronized (pending_output) { + for (String s : pending_output) + System.out.print(s); + pending_output.clear(); + } } public void flush_input(int timeout) throws InterruptedException { @@ -422,8 +427,10 @@ public abstract class AltosLink implements Runnable { public void set_callsign(String callsign) { this.callsign = callsign; - printf ("c c %s\n", callsign); - flush_output(); + if (callsign != null) { + printf ("c c %s\n", callsign); + flush_output(); + } } public boolean is_loader() throws InterruptedException { @@ -462,7 +469,7 @@ public abstract class AltosLink implements Runnable { if (telemetry_rate < 0) telemetry_rate = AltosPreferences.telemetry_rate(serial); set_telemetry_rate(telemetry_rate); - if (callsign.equals("")) + if (callsign == null || callsign.equals("")) callsign = AltosPreferences.callsign(); set_callsign(callsign); printf("p\nE 0\n"); diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java index 054ff1d0..ed1f0f19 100644 --- a/altoslib/AltosListenerState.java +++ b/altoslib/AltosListenerState.java @@ -17,7 +17,9 @@ package org.altusmetrum.altoslib_5; -public class AltosListenerState { +import java.io.*; + +public class AltosListenerState implements Serializable { public int crc_errors; public double battery; diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index 1fa8877b..8784bb81 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -18,8 +18,9 @@ package org.altusmetrum.altoslib_5; import java.util.concurrent.*; +import java.io.*; -public class AltosMag implements Cloneable { +public class AltosMag implements Cloneable, Serializable { public int along; public int across; public int through; diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 81e0641c..97e17164 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -18,8 +18,9 @@ package org.altusmetrum.altoslib_5; import java.util.concurrent.*; +import java.io.*; -public class AltosMs5607 { +public class AltosMs5607 implements Serializable { public int reserved; public int sens; public int off; diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index dba57dcb..5fe810d7 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -41,6 +41,9 @@ public class AltosPreferences { /* log file format preference name */ public final static String logfilePreferenceFormat = "LOGFILE-%d"; + /* state preference name */ + public final static String statePreferenceFormat = "STATE-%d"; + /* voice preference name */ public final static String voicePreference = "VOICE"; @@ -333,6 +336,48 @@ public class AltosPreferences { } } + public static void set_state(int serial, AltosState state, AltosListenerState listener_state) { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + ObjectOutputStream oos = new ObjectOutputStream(baos); + + AltosSavedState saved_state = new AltosSavedState(state, listener_state); + oos.writeObject(saved_state); + + byte[] bytes = baos.toByteArray(); + + synchronized(backend) { + backend.putBytes(String.format(statePreferenceFormat, serial), bytes); + flush_preferences(); + } + } catch (IOException ie) { + } + } + + public static AltosSavedState state(int serial) { + byte[] bytes = null; + + synchronized(backend) { + bytes = backend.getBytes(String.format(statePreferenceFormat, serial), null); + } + + if (bytes == null) + return null; + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + + try { + ObjectInputStream ois = new ObjectInputStream(bais); + AltosSavedState saved_state = (AltosSavedState) ois.readObject(); + return saved_state; + } catch (IOException ie) { + } catch (ClassNotFoundException ce) { + } + return null; + } + public static void set_scanning_telemetry(int new_scanning_telemetry) { synchronized (backend) { scanning_telemetry = new_scanning_telemetry; diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java index 76a99acb..9bb4c99b 100644 --- a/altoslib/AltosPreferencesBackend.java +++ b/altoslib/AltosPreferencesBackend.java @@ -33,6 +33,9 @@ public interface AltosPreferencesBackend { public boolean getBoolean(String key, boolean def); public void putBoolean(String key, boolean value); + public byte[] getBytes(String key, byte[] def); + public void putBytes(String key, byte[] value); + public boolean nodeExists(String key); public AltosPreferencesBackend node(String key); diff --git a/altoslib/AltosSavedState.java b/altoslib/AltosSavedState.java new file mode 100644 index 00000000..4b010b31 --- /dev/null +++ b/altoslib/AltosSavedState.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2014 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_5; + +import java.io.*; + +public class AltosSavedState implements Serializable { + public AltosState state; + public AltosListenerState listener_state; + + public AltosSavedState(AltosState state, AltosListenerState listener_state) { + this.state = state; + this.listener_state = listener_state; + } +} diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 830e95f3..5be008b7 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -21,7 +21,9 @@ package org.altusmetrum.altoslib_5; -public class AltosState implements Cloneable { +import java.io.*; + +public class AltosState implements Cloneable, Serializable { public static final int set_position = 1; public static final int set_gps = 2; @@ -43,7 +45,7 @@ public class AltosState implements Cloneable { private int prev_tick; public int boost_tick; - class AltosValue { + class AltosValue implements Serializable{ double value; double prev_value; private double max_value; @@ -179,9 +181,9 @@ public class AltosState implements Cloneable { } } - class AltosCValue { + class AltosCValue implements Serializable { - class AltosIValue extends AltosValue { + class AltosIValue extends AltosValue implements Serializable { boolean can_max() { return c_can_max(); } @@ -312,7 +314,7 @@ public class AltosState implements Cloneable { ground_altitude.set_measured(a, time); } - class AltosGpsGroundAltitude extends AltosValue { + class AltosGpsGroundAltitude extends AltosValue implements Serializable { void set(double a, double t) { super.set(a, t); pad_alt = value(); @@ -336,7 +338,7 @@ public class AltosState implements Cloneable { gps_ground_altitude.set(a, time); } - class AltosGroundPressure extends AltosCValue { + class AltosGroundPressure extends AltosCValue implements Serializable { void set_filtered(double p, double time) { computed.set_filtered(p, time); if (!is_measured()) @@ -359,7 +361,7 @@ public class AltosState implements Cloneable { ground_pressure.set_measured(pressure, time); } - class AltosAltitude extends AltosCValue { + class AltosAltitude extends AltosCValue implements Serializable { private void set_speed(AltosValue v) { if (!acceleration.is_measured() || !ascent) @@ -381,7 +383,7 @@ public class AltosState implements Cloneable { private AltosAltitude altitude; - class AltosGpsAltitude extends AltosValue { + class AltosGpsAltitude extends AltosValue implements Serializable { private void set_gps_height() { double a = value(); @@ -464,7 +466,7 @@ public class AltosState implements Cloneable { return gps_speed.max(); } - class AltosPressure extends AltosValue { + class AltosPressure extends AltosValue implements Serializable { void set(double p, double time) { super.set(p, time); if (state == AltosLib.ao_flight_pad) @@ -534,7 +536,7 @@ public class AltosState implements Cloneable { return AltosLib.MISSING; } - class AltosSpeed extends AltosCValue { + class AltosSpeed extends AltosCValue implements Serializable { boolean can_max() { return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless; @@ -588,7 +590,7 @@ public class AltosState implements Cloneable { return AltosLib.MISSING; } - class AltosAccel extends AltosCValue { + class AltosAccel extends AltosCValue implements Serializable { boolean can_max() { return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless; diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 2805742e..8aff2767 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -82,6 +82,7 @@ altoslib_JAVA = \ AltosProgrammer.java \ AltosReplayReader.java \ AltosRomconfig.java \ + AltosSavedState.java \ AltosSelfFlash.java \ AltosSensorMM.java \ AltosSensorEMini.java \ diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index 67b7a989..0230ff2f 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -102,6 +102,15 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl SwingUtilities.invokeLater(r); } + public void failed() { + Runnable r = new Runnable() { + public void run() { + close(); + } + }; + SwingUtilities.invokeLater(r); + } + Container bag; AltosUIFreqList frequencies; JTextField callsign_value; @@ -174,6 +183,19 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl } } + private void close() { + try { + disconnect(); + } catch (Exception ex) { + System.out.printf("Exception %s\n", ex.toString()); + for (StackTraceElement el : ex.getStackTrace()) + System.out.printf("%s\n", el.toString()); + } + setVisible(false); + dispose(); + AltosUIPreferences.unregister_font_listener(AltosIdleMonitorUI.this); + } + public AltosIdleMonitorUI(JFrame in_owner) throws FileNotFoundException, TimeoutException, InterruptedException { @@ -184,9 +206,10 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl serial = device.getSerial(); - AltosLink link; + AltosSerial link; try { link = new AltosSerial(device); + link.set_frame(this); } catch (Exception ex) { idle_exception(in_owner, ex); return; @@ -248,16 +271,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - try { - disconnect(); - } catch (Exception ex) { - System.out.printf("Exception %s\n", ex.toString()); - for (StackTraceElement el : ex.getStackTrace()) - System.out.printf("%s\n", el.toString()); - } - setVisible(false); - dispose(); - AltosUIPreferences.unregister_font_listener(AltosIdleMonitorUI.this); + close(); } }); diff --git a/altosui/AltosUIPreferencesBackend.java b/altosui/AltosUIPreferencesBackend.java deleted file mode 100644 index b229d7b2..00000000 --- a/altosui/AltosUIPreferencesBackend.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright © 2012 Mike Beattie - * - * 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. - */ - -package altosui; - -import java.io.File; -import java.util.prefs.*; -import org.altusmetrum.altoslib_5.*; -import javax.swing.filechooser.FileSystemView; - -public class AltosUIPreferencesBackend implements AltosPreferencesBackend { - - private Preferences _preferences = null; - - public AltosUIPreferencesBackend() { - _preferences = Preferences.userRoot().node("/org/altusmetrum/altosui"); - } - - public AltosUIPreferencesBackend(Preferences in_preferences) { - _preferences = in_preferences; - } - - public String getString(String key, String def) { - return _preferences.get(key, def); - } - public void putString(String key, String value) { - _preferences.put(key, value); - } - - public int getInt(String key, int def) { - return _preferences.getInt(key, def); - } - public void putInt(String key, int value) { - _preferences.putInt(key, value); - } - - public double getDouble(String key, double def) { - return _preferences.getDouble(key, def); - } - public void putDouble(String key, double value) { - _preferences.putDouble(key, value); - } - - public boolean getBoolean(String key, boolean def) { - return _preferences.getBoolean(key, def); - } - public void putBoolean(String key, boolean value) { - _preferences.putBoolean(key, value); - } - - public boolean nodeExists(String key) { - try { - return _preferences.nodeExists(key); - } catch (BackingStoreException be) { - return false; - } - } - - public AltosPreferencesBackend node(String key) { - return new AltosUIPreferencesBackend(_preferences.node(key)); - } - - public String[] keys() { - try { - return _preferences.keys(); - } catch (BackingStoreException be) { - return null; - } - } - - public void remove(String key) { - _preferences.remove(key); - } - - public void flush() { - try { - _preferences.flush(); - } catch (BackingStoreException ee) { - System.err.printf("Cannot save preferences\n"); - } - } - - public File homeDirectory() { - /* Use the file system view default directory */ - return FileSystemView.getFileSystemView().getDefaultDirectory(); - } -} diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 48f58933..1531e109 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -32,7 +32,6 @@ altosui_JAVA = \ AltosLaunchUI.java \ AltosLanded.java \ AltosPad.java \ - AltosUIPreferencesBackend.java \ AltosUI.java \ AltosGraphUI.java diff --git a/altosuilib/AltosInfoTable.java b/altosuilib/AltosInfoTable.java index 625fe76f..91cc43bb 100644 --- a/altosuilib/AltosInfoTable.java +++ b/altosuilib/AltosInfoTable.java @@ -207,7 +207,7 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar state.gps.climb_rate); if (state.gps.h_error != AltosLib.MISSING && state.gps.v_error != AltosLib.MISSING) - info_add_row(1, "GPS error", "%6d m(h)%3d m(v)", + info_add_row(1, "GPS error", "%6.0f m(h)%6.0f m(v)", state.gps.h_error, state.gps.v_error); if (state.gps.pdop != AltosLib.MISSING && state.gps.hdop != AltosLib.MISSING && diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java index 8fa7dfe6..ccadf07c 100644 --- a/altosuilib/AltosUILib.java +++ b/altosuilib/AltosUILib.java @@ -82,11 +82,23 @@ public class AltosUILib extends AltosLib { static public boolean loaded_library = false; static public boolean has_bluetooth = false; - static final String[] library_names = { "altos", "altos32", "altos64" }; + static final String[] library_names_32 = { "altos", "altos32", "altos64" }; + static final String[] library_names_64 = { "altos", "altos64", "altos32" }; public static boolean load_library() { if (!initialized) { - for (String name : library_names) { + String model = System.getProperty("sun.arch.data.model", "missing"); + boolean is_64 = false; + if (model.equals("64")) { + is_64 = true; + } else if (model.equals("32")) { + ; + } else { + String arch = System.getProperty("os.arch", "missing"); + if (arch.endsWith("64")) + is_64 = true; + } + for (String name : is_64 ? library_names_64 : library_names_32) { try { System.loadLibrary(name); libaltos.altos_init(); diff --git a/altosuilib/AltosUIPreferencesBackend.java b/altosuilib/AltosUIPreferencesBackend.java index 4048fd83..8d4431f1 100644 --- a/altosuilib/AltosUIPreferencesBackend.java +++ b/altosuilib/AltosUIPreferencesBackend.java @@ -62,6 +62,14 @@ public class AltosUIPreferencesBackend implements AltosPreferencesBackend { _preferences.putBoolean(key, value); } + public byte[] getBytes(String key, byte[] def) { + return _preferences.getByteArray(key, def); + } + + public void putBytes(String key, byte[] value) { + _preferences.putByteArray(key, value); + } + public boolean nodeExists(String key) { try { return _preferences.nodeExists(key); diff --git a/ao-tools/ao-send-telem/ao-send-telem.c b/ao-tools/ao-send-telem/ao-send-telem.c index 26c3263e..ef6f892c 100644 --- a/ao-tools/ao-send-telem/ao-send-telem.c +++ b/ao-tools/ao-send-telem/ao-send-telem.c @@ -29,12 +29,14 @@ static const struct option options[] = { { .name = "device", .has_arg = 1, .val = 'D' }, { .name = "frequency", .has_arg = 1, .val = 'F' }, { .name = "realtime", .has_arg = 0, .val = 'R' }, + { .name = "verbose", .has_arg = 0, .val = 'v' }, + { .name = "fake", .has_arg = 0, .val = 'f' }, { 0, 0, 0, 0}, }; static void usage(char *program) { - fprintf(stderr, "usage: %s [--tty ] [--device ] [--frequency ] [--realtime] file.telem ...\n", program); + fprintf(stderr, "usage: %s [--tty ] [--device ] [--frequency ] [--realtime] [--verbose] [--fake] file.telem ...\n", program); exit(1); } @@ -126,7 +128,7 @@ send_telem(struct cc_usb *cc, union ao_telemetry_all *telem) for (i = 0; i < 0x20; i++) cc_usb_printf(cc, "%02x", b[i]); cc_usb_sync(cc); -} +} static void do_delay(uint16_t now, uint16_t then) @@ -173,9 +175,11 @@ main (int argc, char **argv) uint16_t last_tick; int started; int realtime = 0; - + int verbose = 0; + int fake = 0; + int rate = 0; - while ((c = getopt_long(argc, argv, "RT:D:F:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "vRfT:D:F:r:", options, NULL)) != -1) { switch (c) { case 'T': tty = optarg; @@ -189,6 +193,30 @@ main (int argc, char **argv) case 'R': realtime = 1; break; + case 'v': + verbose++; + break; + case 'f': + fake++; + break; + case 'r': + rate = atoi(optarg); + switch (rate) { + case 38400: + rate = 0; + break; + case 9600: + rate = 1; + break; + case 2400: + rate = 2; + break; + default: + fprintf(stderr, "Rate %d isn't 38400, 9600 or 2400\n", rate); + usage(argv[0]); + break; + } + break; default: usage(argv[0]); break; @@ -206,42 +234,65 @@ main (int argc, char **argv) cc_usb_printf(cc, "m 0\n"); cc_usb_printf(cc, "c F %d\n", freq); - for (i = optind; i < argc; i++) { - file = fopen(argv[i], "r"); - if (!file) { - perror(argv[i]); - ret++; - continue; + cc_usb_printf(cc, "c T %d\n", rate); + + if (fake) { + union ao_telemetry_all telem; + uint16_t tick; + int i; + + memset(&telem, '\0', sizeof (telem)); + telem.generic.serial = 1; + telem.generic.type = 0; + for (i = 0; i < sizeof (telem.generic.payload); i++) + telem.generic.payload[i] = i & 7; + for (;;) { + telem.generic.tick += 50; + send_telem(cc, &telem); + do_delay(50, 0); } - started = 0; - last_tick = 0; - while (fgets(line, sizeof (line), file)) { - union ao_telemetry_all telem; - - if (cc_telemetry_parse(line, &telem)) { - /* - * Skip packets with CRC errors. - */ - if ((telem.generic.status & (1 << 7)) == 0) - continue; - - if (started) { - do_delay(telem.generic.tick, last_tick); - last_tick = telem.generic.tick; - send_telem(cc, &telem); - } else { - enum ao_flight_state state = packet_state(&telem); - add_telem(&telem); - if (ao_flight_pad < state && state < ao_flight_landed) { - printf ("started\n"); - started = 1; - last_tick = send_queued(cc, realtime); + } else { + for (i = optind; i < argc; i++) { + file = fopen(argv[i], "r"); + if (!file) { + perror(argv[i]); + ret++; + continue; + } + started = 0; + last_tick = 0; + while (fgets(line, sizeof (line), file)) { + union ao_telemetry_all telem; + + if (cc_telemetry_parse(line, &telem)) { + /* + * Skip packets with CRC errors. + */ + if ((telem.generic.status & (1 << 7)) == 0) + continue; + + if (verbose) + printf ("type %4d\n", telem.generic.type); + + if (started || realtime) { + do_delay(telem.generic.tick, last_tick); + last_tick = telem.generic.tick; + send_telem(cc, &telem); + } else { + enum ao_flight_state state = packet_state(&telem); + printf ("\tstate %4d\n", state); + add_telem(&telem); + if (ao_flight_pad < state && state < ao_flight_landed) { + printf ("started\n"); + started = 1; + last_tick = send_queued(cc, realtime); + } } } } - } - fclose (file); + fclose (file); + } } return ret; } diff --git a/src/Makefile b/src/Makefile index 20126de6..a5d7b0f3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,6 +35,7 @@ ARMM3DIRS=\ telegps-v1.0 telegps-v1.0/flash-loader \ telelco-v0.2 telelco-v0.2/flash-loader \ telescience-v0.2 telescience-v0.2/flash-loader \ + teledongle-v1.9 teledongle-v1.9/flash-loader \ teleballoon-v2.0 ARMM0DIRS=\ diff --git a/src/attiny/ao_arch.h b/src/attiny/ao_arch.h index 8140dd30..6ca12af6 100644 --- a/src/attiny/ao_arch.h +++ b/src/attiny/ao_arch.h @@ -31,6 +31,8 @@ #define AO_STACK_SIZE 116 +#define AO_PORT_TYPE uint8_t + /* Various definitions to make GCC look more like SDCC */ #define ao_arch_naked_declare __attribute__((naked)) diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index d626e830..f8c7f042 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -41,6 +41,8 @@ #define AO_STACK_SIZE 116 #endif +#define AO_PORT_TYPE uint8_t + /* Various definitions to make GCC look more like SDCC */ #define ao_arch_naked_declare __attribute__((naked)) diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index fcac331b..b3c6b5dc 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -40,6 +40,8 @@ #define AO_STACK_END 0xfe #define AO_STACK_SIZE (AO_STACK_END - AO_STACK_START + 1) +#define AO_PORT_TYPE uint8_t + #define ao_arch_reboot() do { \ WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64; \ ao_delay(AO_SEC_TO_TICKS(2)); \ diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index cf61acfe..9e116d62 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -246,6 +246,8 @@ ao_radio_idle(void) } /* Flush any pending TX bytes */ ao_radio_strobe(CC115L_SFTX); + /* Make sure the RF calibration is current */ + ao_radio_strobe(CC115L_SCAL); } /* @@ -325,23 +327,22 @@ static const struct { static const uint16_t packet_setup[] = { CC115L_MDMCFG3, (PACKET_DRATE_M), - CC115L_MDMCFG2, (0x00 | - (CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | + CC115L_MDMCFG2, ((CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | (0 << CC115L_MDMCFG2_MANCHESTER_EN) | (CC115L_MDMCFG2_SYNC_MODE_16BITS << CC115L_MDMCFG2_SYNC_MODE)), }; /* - * RDF deviation is 5kHz + * RDF deviation is 3kHz * * fdev = fosc >> 17 * (8 + dev_m) << dev_e * - * 26e6 / (2 ** 17) * (8 + 4) * (2 ** 1) = 4761Hz + * 26e6 / (2 ** 17) * (8 + 7) * (2 ** 0) = 2975 */ -#define RDF_DEV_E 1 -#define RDF_DEV_M 4 +#define RDF_DEV_E 0 +#define RDF_DEV_M 7 /* * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone) @@ -364,8 +365,7 @@ static const uint16_t rdf_setup[] = { CC115L_MDMCFG4, ((0xf << 4) | (RDF_DRATE_E << CC115L_MDMCFG4_DRATE_E)), CC115L_MDMCFG3, (RDF_DRATE_M), - CC115L_MDMCFG2, (0x00 | - (CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | + CC115L_MDMCFG2, ((CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | (0 << CC115L_MDMCFG2_MANCHESTER_EN) | (CC115L_MDMCFG2_SYNC_MODE_NONE << CC115L_MDMCFG2_SYNC_MODE)), }; @@ -401,8 +401,7 @@ static const uint16_t aprs_setup[] = { CC115L_MDMCFG4, ((0xf << 4) | (APRS_DRATE_E << CC115L_MDMCFG4_DRATE_E)), CC115L_MDMCFG3, (APRS_DRATE_M), - CC115L_MDMCFG2, (0x00 | - (CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | + CC115L_MDMCFG2, ((CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | (0 << CC115L_MDMCFG2_MANCHESTER_EN) | (CC115L_MDMCFG2_SYNC_MODE_NONE << CC115L_MDMCFG2_SYNC_MODE)), }; @@ -491,16 +490,21 @@ static const uint16_t radio_setup[] = { AO_CC115L_DONE_INT_GPIO_IOCFG, CC115L_IOCFG_GPIO_CFG_PA_PD | (1 << CC115L_IOCFG_GPIO_INV), CC115L_FIFOTHR, 0x47, /* TX FIFO Thresholds */ - CC115L_MDMCFG1, (0x00 | - (CC115L_MDMCFG1_NUM_PREAMBLE_4 << CC115L_MDMCFG1_NUM_PREAMBLE) | - (1 << CC115L_MDMCFG1_CHANSPC_E)), + CC115L_MDMCFG1, /* Modem Configuration */ + ((CC115L_MDMCFG1_NUM_PREAMBLE_4 << CC115L_MDMCFG1_NUM_PREAMBLE) | + (1 << CC115L_MDMCFG1_CHANSPC_E)), CC115L_MDMCFG0, 248, /* Channel spacing M value (100kHz channels) */ + CC115L_MCSM1, 0x30, /* Main Radio Control State Machine Configuration */ CC115L_MCSM0, 0x38, /* Main Radio Control State Machine Configuration */ CC115L_RESERVED_0X20, 0xfb, /* Use setting from SmartRF Studio */ + CC115L_FREND0, 0x10, /* Front End TX Configuration */ CC115L_FSCAL3, 0xe9, /* Frequency Synthesizer Calibration */ CC115L_FSCAL2, 0x2a, /* Frequency Synthesizer Calibration */ CC115L_FSCAL1, 0x00, /* Frequency Synthesizer Calibration */ CC115L_FSCAL0, 0x1f, /* Frequency Synthesizer Calibration */ + CC115L_RESERVED_0X29, 0x59, /* RESERVED */ + CC115L_RESERVED_0X2A, 0x7f, /* RESERVED */ + CC115L_RESERVED_0X2B, 0x3f, /* RESERVED */ CC115L_TEST2, 0x81, /* Various Test Settings */ CC115L_TEST1, 0x35, /* Various Test Settings */ CC115L_TEST0, 0x09, /* Various Test Settings */ @@ -508,6 +512,12 @@ static const uint16_t radio_setup[] = { static uint8_t ao_radio_configured = 0; +#if HAS_RADIO_POWER +#define RADIO_POWER ao_config.radio_power +#else +#define RADIO_POWER 0xc0 +#endif + static void ao_radio_setup(void) { @@ -523,6 +533,8 @@ ao_radio_setup(void) ao_config_get(); + ao_radio_reg_write(CC115L_PA, RADIO_POWER); + ao_radio_strobe(CC115L_SCAL); ao_radio_configured = 1; @@ -553,6 +565,8 @@ ao_radio_get(void) ao_radio_reg_write(CC115L_FREQ1, ao_config.radio_setting >> 8); ao_radio_reg_write(CC115L_FREQ0, ao_config.radio_setting); last_radio_setting = ao_config.radio_setting; + /* Make sure the RF calibration is current */ + ao_radio_strobe(CC115L_SCAL); } if (ao_config.radio_rate != last_radio_rate) { ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET_TX; @@ -666,23 +680,11 @@ ao_radio_rdf_abort(void) #define POWER_STEP 0x08 -#if HAS_RADIO_POWER -#define RADIO_POWER ao_config.radio_power -#else -#define RADIO_POWER 0xc0 -#endif - static void ao_radio_stx(void) { - uint8_t power; ao_radio_pa_on(); - ao_radio_reg_write(CC115L_PA, 0); ao_radio_strobe(CC115L_STX); - for (power = POWER_STEP; power < RADIO_POWER; power += POWER_STEP) - ao_radio_reg_write(CC115L_PA, power); - if (power != RADIO_POWER) - ao_radio_reg_write(CC115L_PA, RADIO_POWER); } static void diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index a69cdc11..8546900e 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -21,30 +21,30 @@ #include #include -#define AO_RADIO_MAX_RECV sizeof(struct ao_packet) -#define AO_RADIO_MAX_SEND sizeof(struct ao_packet) - static uint8_t ao_radio_mutex; static uint8_t ao_radio_wake; /* radio ready. Also used as sleep address */ static uint8_t ao_radio_abort; /* radio operation should abort */ -static uint8_t ao_radio_mcu_wake; /* MARC status change */ -static uint8_t ao_radio_marc_status; /* Last read MARC status value */ -static uint8_t ao_radio_tx_finished; /* MARC status indicates TX finished */ int8_t ao_radio_rssi; /* Last received RSSI value */ -#define CC1200_DEBUG 1 -#define CC1200_TRACE 1 +#ifndef CC1200_DEBUG +#define CC1200_DEBUG 0 +#endif + +#ifndef CC1200_LOW_LEVEL_DEBUG +#define CC1200_LOW_LEVEL_DEBUG 0 +#endif + +#define CC1200_TRACE 0 +#define CC1200_APRS_TRACE 0 extern const uint32_t ao_radio_cal; -#define FOSC 32000000 +#define FOSC 40000000 -#define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_125kHz, task_id) -#define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_125kHz) +#define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_FAST) #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS) -#define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1200_SPI_BUS) #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1200_SPI_BUS) #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1200_SPI_BUS) #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1200_SPI_BUS) @@ -128,7 +128,6 @@ ao_radio_strobe(uint8_t addr) return in; } -#if 0 static uint8_t ao_radio_fifo_read(uint8_t *data, uint8_t len) { @@ -143,7 +142,6 @@ ao_radio_fifo_read(uint8_t *data, uint8_t len) ao_radio_deselect(); return status; } -#endif static uint8_t ao_radio_fifo_write_start(void) @@ -164,7 +162,7 @@ static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) { } static uint8_t -ao_radio_fifo_write(uint8_t *data, uint8_t len) +ao_radio_fifo_write(const uint8_t *data, uint8_t len) { uint8_t status = ao_radio_fifo_write_start(); ao_radio_spi_send(data, len); @@ -185,13 +183,11 @@ ao_radio_tx_fifo_space(void) return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES); } -#if CC1200_DEBUG || CC1200_TRACE static uint8_t ao_radio_status(void) { return ao_radio_strobe (CC1200_SNOP); } -#endif void ao_radio_recv_abort(void) @@ -202,25 +198,6 @@ ao_radio_recv_abort(void) #define ao_radio_rdf_value 0x55 -static uint8_t -ao_radio_get_marc_status(void) -{ - return ao_radio_reg_read(CC1200_MARC_STATUS1); -} - -static void -ao_radio_check_marc_status(void) -{ - ao_radio_mcu_wake = 0; - ao_radio_marc_status = ao_radio_get_marc_status(); - - /* Anyt other than 'tx/rx finished' means an error occurred */ - if (ao_radio_marc_status & ~(CC1200_MARC_STATUS1_TX_FINISHED|CC1200_MARC_STATUS1_RX_FINISHED)) - ao_radio_abort = 1; - if (ao_radio_marc_status & (CC1200_MARC_STATUS1_TX_FINISHED)) - ao_radio_tx_finished = 1; -} - static void ao_radio_isr(void) { @@ -232,12 +209,17 @@ ao_radio_isr(void) static void ao_radio_start_tx(void) { - ao_exti_set_callback(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, ao_radio_isr); ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); - ao_radio_tx_finished = 0; ao_radio_strobe(CC1200_STX); } +static void +ao_radio_start_rx(void) +{ + ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); + ao_radio_strobe(CC1200_SRX); +} + static void ao_radio_idle(void) { @@ -250,37 +232,40 @@ ao_radio_idle(void) if (state == CC1200_STATUS_STATE_RX_FIFO_ERROR) ao_radio_strobe(CC1200_SFRX); } - /* Flush any pending TX bytes */ + /* Flush any pending data in the fifos */ ao_radio_strobe(CC1200_SFTX); + ao_radio_strobe(CC1200_SFRX); + /* Make sure the RF calibration is current */ + ao_radio_strobe(CC1200_SCAL); } /* * Packet deviation * - * fdev = fosc >> 24 * (256 + dev_m) << dev_e + * fdev = fosc >> 22 * (256 + dev_m) << dev_e * * Deviation for 38400 baud should be 20.5kHz: * - * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 5) = 20508Hz + * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 3) = 20523Hz * * Deviation for 9600 baud should be 5.125kHz: * - * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 3) = 5127Hz + * 40e6 / (2 ** 22) * (256 + 13) * (2 ** 1) = 5131Hz * * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and * cc115l can't do that, so we'll use 1.5kHz instead: * - * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 1) = 1499Hz + * 40e6 / (2 ** 21) * (79) = 1506Hz */ -#define PACKET_DEV_M_384 80 -#define PACKET_DEV_E_384 5 +#define PACKET_DEV_M_384 13 +#define PACKET_DEV_E_384 3 -#define PACKET_DEV_M_96 80 -#define PACKET_DEV_E_96 3 +#define PACKET_DEV_M_96 13 +#define PACKET_DEV_E_96 1 -#define PACKET_DEV_M_24 137 -#define PACKET_DEV_E_24 1 +#define PACKET_DEV_M_24 79 +#define PACKET_DEV_E_24 0 /* * For our packet data @@ -299,37 +284,37 @@ ao_radio_idle(void) * * Symbol rate 38400 Baud: * - * DATARATE_M = 239914 - * DATARATE_E = 9 - * CHANBW = 79.4 (79.4) + * DATARATE_M = 1013008 + * DATARATE_E = 8 + * CHANBW = 104.16667 * * Symbol rate 9600 Baud: * - * DATARATE_M = 239914 - * DATARATE_E = 7 - * CHANBW = 19.9 (round to 19.8) + * DATARATE_M = 1013008 + * DATARATE_E = 6 + * CHANBW = 26.042 (round to 19.8) * * Symbol rate 2400 Baud: * - * DATARATE_M = 239914 - * DATARATE_E = 5 + * DATARATE_M = 1013008 + * DATARATE_E = 4 * CHANBW = 5.0 (round to 9.5) */ -#define PACKET_SYMBOL_RATE_M 239914 +#define PACKET_SYMBOL_RATE_M 1013008 -#define PACKET_SYMBOL_RATE_E_384 9 +#define PACKET_SYMBOL_RATE_E_384 8 /* 200 / 2 = 100 */ #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ - (21 << CC1200_CHAN_BW_BB_CIC_DECFACT)) + (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) -#define PACKET_SYMBOL_RATE_E_96 7 +#define PACKET_SYMBOL_RATE_E_96 6 /* 200 / 10 = 20 */ #define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ - (21 << CC1200_CHAN_BW_BB_CIC_DECFACT)) + (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) -#define PACKET_SYMBOL_RATE_E_24 5 +#define PACKET_SYMBOL_RATE_E_24 4 /* 200 / 25 = 8 */ #define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ (44 << CC1200_CHAN_BW_BB_CIC_DECFACT)) @@ -337,17 +322,17 @@ ao_radio_idle(void) static const uint16_t packet_setup[] = { CC1200_SYMBOL_RATE1, ((PACKET_SYMBOL_RATE_M >> 8) & 0xff), CC1200_SYMBOL_RATE0, ((PACKET_SYMBOL_RATE_M >> 0) & 0xff), - CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | - (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), - CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) | - (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | - (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) | - (0 << CC1200_PKT_CFG1_APPEND_STATUS)), - CC1200_PKT_CFG0, ((0 << CC1200_PKT_CFG0_RESERVED7) | - (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | - (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | - (0 << CC1200_PKT_CFG0_UART_MODE_EN) | - (0 << CC1200_PKT_CFG0_UART_SWAP_EN)), + CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */ + ((0 << CC1200_PKT_CFG2_FG_MODE_EN) | + (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | + (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), + CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */ + ((1 << CC1200_PKT_CFG1_FEC_EN) | + (1 << CC1200_PKT_CFG1_WHITE_DATA) | + (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) | + (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | + (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) | + (1 << CC1200_PKT_CFG1_APPEND_STATUS)), CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) | (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)), }; @@ -357,10 +342,14 @@ static const uint16_t packet_setup_384[] = { CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) | (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) | (PACKET_DEV_E_384 << CC1200_MODCFG_DEV_E_DEV_E)), - CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) | + CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_384 << CC1200_SYMBOL_RATE2_DATARATE_E) | (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), CC1200_CHAN_BW, PACKET_CHAN_BW_384, - CC1200_PA_CFG0, 0x7b, + CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ + ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | + (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | + (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) | + (0 << CC1200_MDMCFG2_CFM_DATA_EN)), }; static const uint16_t packet_setup_96[] = { @@ -368,10 +357,14 @@ static const uint16_t packet_setup_96[] = { CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) | (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) | (PACKET_DEV_E_96 << CC1200_MODCFG_DEV_E_DEV_E)), - CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) | + CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_96 << CC1200_SYMBOL_RATE2_DATARATE_E) | (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), CC1200_CHAN_BW, PACKET_CHAN_BW_96, - CC1200_PA_CFG0, 0x7d, + CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ + ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | + (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | + (CC1200_MDMCFG2_UPSAMPLER_P_32 << CC1200_MDMCFG2_UPSAMPLER_P) | + (0 << CC1200_MDMCFG2_CFM_DATA_EN)), }; static const uint16_t packet_setup_24[] = { @@ -379,34 +372,27 @@ static const uint16_t packet_setup_24[] = { CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) | (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) | (PACKET_DEV_E_24 << CC1200_MODCFG_DEV_E_DEV_E)), - CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) | + CC1200_SYMBOL_RATE2, ((PACKET_SYMBOL_RATE_E_24 << CC1200_SYMBOL_RATE2_DATARATE_E) | (((PACKET_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), CC1200_CHAN_BW, PACKET_CHAN_BW_24, - CC1200_PA_CFG0, 0x7e, -}; - -static const uint16_t packet_tx_setup[] = { - CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | - (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), - AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_RX0TX1_CFG, -}; - -static const uint16_t packet_rx_setup[] = { - CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | - (CC1200_PKT_CFG2_PKT_FORMAT_SYNCHRONOUS_SERIAL << CC1200_PKT_CFG2_PKT_FORMAT)), - AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_CLKEN_SOFT, + CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ + ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | + (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | + (CC1200_MDMCFG2_UPSAMPLER_P_64 << CC1200_MDMCFG2_UPSAMPLER_P) | + (0 << CC1200_MDMCFG2_CFM_DATA_EN)), }; /* - * RDF deviation is 5kHz + * RDF deviation is 3kHz * - * fdev = fosc >> 24 * (256 + dev_m) << dev_e + * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0 + * fdev = fosc >> 21 * dev_m dev_e == 0 * - * 32e6Hz / (2 ** 24) * (256 + 71) * (2 ** 3) = 4989 + * 40e6 / (2 ** 21) * 157 = 2995Hz */ -#define RDF_DEV_E 3 -#define RDF_DEV_M 71 +#define RDF_DEV_E 0 +#define RDF_DEV_M 157 /* * For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone) @@ -415,13 +401,13 @@ static const uint16_t packet_rx_setup[] = { * Rdata = -------------------------------------- * fosc * 2 ** 39 * - * DATARATE_M = 25166 - * DATARATE_E = 5 + * DATARATE_M = 669411 + * DATARATE_E = 4 * * To make the tone last for 200ms, we need 2000 * .2 = 400 bits or 50 bytes */ -#define RDF_SYMBOL_RATE_E 5 -#define RDF_SYMBOL_RATE_M 25166 +#define RDF_SYMBOL_RATE_E 4 +#define RDF_SYMBOL_RATE_M 669411 #define RDF_PACKET_LEN 50 static const uint16_t rdf_setup[] = { @@ -429,36 +415,42 @@ static const uint16_t rdf_setup[] = { CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) | (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) | (RDF_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)), - CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) | + CC1200_SYMBOL_RATE2, ((RDF_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) | (((RDF_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), - CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff), - CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff), - CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | - (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), - CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) | - (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | - (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) | - (0 << CC1200_PKT_CFG1_APPEND_STATUS)), - CC1200_PKT_CFG0, ((0 << CC1200_PKT_CFG0_RESERVED7) | - (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | - (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | - (0 << CC1200_PKT_CFG0_UART_MODE_EN) | - (0 << CC1200_PKT_CFG0_UART_SWAP_EN)), - CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) | - (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)), - CC1200_PA_CFG0, 0x7e, + CC1200_SYMBOL_RATE1, ((RDF_SYMBOL_RATE_M >> 8) & 0xff), + CC1200_SYMBOL_RATE0, ((RDF_SYMBOL_RATE_M >> 0) & 0xff), + CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */ + ((0 << CC1200_PKT_CFG2_FG_MODE_EN) | + (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | + (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), + CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */ + ((0 << CC1200_PKT_CFG1_FEC_EN) | + (0 << CC1200_PKT_CFG1_WHITE_DATA) | + (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) | + (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | + (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) | + (0 << CC1200_PKT_CFG1_APPEND_STATUS)), + CC1200_PREAMBLE_CFG1, + ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) | + (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)), + CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ + ((0 << CC1200_MDMCFG2_ASK_SHAPE) | + (0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | + (12 << CC1200_MDMCFG2_UPSAMPLER_P) | + (0 << CC1200_MDMCFG2_CFM_DATA_EN)), }; /* * APRS deviation is 3kHz * - * fdev = fosc >> 24 * (256 + dev_m) << dev_e + * fdev = fosc >> 22 * (256 + dev_m) << dev_e dev_e != 0 + * fdev = fosc >> 21 * dev_m dev_e == 0 * - * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 2) = 2998Hz + * 40e6 / (2 ** 21) * 157 = 2995Hz */ -#define APRS_DEV_E 2 -#define APRS_DEV_M 137 +#define APRS_DEV_E 0 +#define APRS_DEV_M 157 /* * For our APRS beacon, set the symbol rate to 9.6kBaud (8x oversampling for 1200 baud data rate) @@ -467,33 +459,48 @@ static const uint16_t rdf_setup[] = { * Rdata = -------------------------------------- * fosc * 2 ** 39 * - * DATARATE_M = 239914 - * DATARATE_E = 7 + * DATARATE_M = 1013008 + * DATARATE_E = 6 * * Rdata = 9599.998593330383301 * */ -#define APRS_SYMBOL_RATE_E 7 -#define APRS_SYMBOL_RATE_M 239914 +#define APRS_SYMBOL_RATE_E 6 +#define APRS_SYMBOL_RATE_M 1013008 static const uint16_t aprs_setup[] = { CC1200_DEVIATION_M, APRS_DEV_M, CC1200_MODCFG_DEV_E, ((CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1200_MODCFG_DEV_E_MODEM_MODE) | (CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1200_MODCFG_DEV_E_MOD_FORMAT) | (APRS_DEV_E << CC1200_MODCFG_DEV_E_DEV_E)), - CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) | + CC1200_SYMBOL_RATE2, ((APRS_SYMBOL_RATE_E << CC1200_SYMBOL_RATE2_DATARATE_E) | (((APRS_SYMBOL_RATE_M >> 16) & CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK) << CC1200_SYMBOL_RATE2_DATARATE_M_19_16)), - CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff), - CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff), - CC1200_PKT_CFG2, ((CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | - (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), - CC1200_PKT_CFG1, ((0 << CC1200_PKT_CFG1_WHITE_DATA) | - (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | - (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) | - (0 << CC1200_PKT_CFG1_APPEND_STATUS)), - CC1200_PREAMBLE_CFG1, ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) | - (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)), - CC1200_PA_CFG0, 0x7d, + CC1200_SYMBOL_RATE1, ((APRS_SYMBOL_RATE_M >> 8) & 0xff), + CC1200_SYMBOL_RATE0, ((APRS_SYMBOL_RATE_M >> 0) & 0xff), + CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */ + ((0 << CC1200_PKT_CFG2_FG_MODE_EN) | + (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | + (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), + CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */ + ((0 << CC1200_PKT_CFG1_FEC_EN) | + (0 << CC1200_PKT_CFG1_WHITE_DATA) | + (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) | + (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | + (CC1200_PKT_CFG1_CRC_CFG_DISABLED << CC1200_PKT_CFG1_CRC_CFG) | + (0 << CC1200_PKT_CFG1_APPEND_STATUS)), + CC1200_PKT_CFG0, /* Packet Configuration Reg. 0 */ + ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | + (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | + (0 << CC1200_PKT_CFG0_UART_MODE_EN) | + (0 << CC1200_PKT_CFG0_UART_SWAP_EN)), + CC1200_PREAMBLE_CFG1, + ((CC1200_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1200_PREAMBLE_CFG1_NUM_PREAMBLE) | + (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)), + CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ + ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | + (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | + (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) | + (0 << CC1200_MDMCFG2_CFM_DATA_EN)), }; /* @@ -521,14 +528,12 @@ static const uint16_t test_setup[] = { (CC1200_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1200_PREAMBLE_CFG1_PREAMBLE_WORD)), }; -#define AO_PKT_CFG0_INFINITE ((0 << CC1200_PKT_CFG0_RESERVED7) | \ - (CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \ +#define AO_PKT_CFG0_INFINITE ((CC1200_PKT_CFG0_LENGTH_CONFIG_INFINITE << CC1200_PKT_CFG0_LENGTH_CONFIG) | \ (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \ (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \ (0 << CC1200_PKT_CFG0_UART_SWAP_EN)) -#define AO_PKT_CFG0_FIXED ((0 << CC1200_PKT_CFG0_RESERVED7) | \ - (CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \ +#define AO_PKT_CFG0_FIXED ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | \ (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | \ (0 << CC1200_PKT_CFG0_UART_MODE_EN) | \ (0 << CC1200_PKT_CFG0_UART_SWAP_EN)) @@ -536,10 +541,9 @@ static const uint16_t test_setup[] = { static uint16_t ao_radio_mode; #define AO_RADIO_MODE_BITS_PACKET 1 -#define AO_RADIO_MODE_BITS_PACKET_TX 2 #define AO_RADIO_MODE_BITS_TX_BUF 4 #define AO_RADIO_MODE_BITS_TX_FINISH 8 -#define AO_RADIO_MODE_BITS_PACKET_RX 16 +#define AO_RADIO_MODE_BITS_RX 16 #define AO_RADIO_MODE_BITS_RDF 32 #define AO_RADIO_MODE_BITS_APRS 64 #define AO_RADIO_MODE_BITS_TEST 128 @@ -547,14 +551,13 @@ static uint16_t ao_radio_mode; #define AO_RADIO_MODE_BITS_FIXED 512 #define AO_RADIO_MODE_NONE 0 -#define AO_RADIO_MODE_PACKET_TX_BUF (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_BUF) -#define AO_RADIO_MODE_PACKET_TX_FINISH (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_TX | AO_RADIO_MODE_BITS_TX_FINISH) -#define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_PACKET_RX) -#define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_TX_FINISH) -#define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) -#define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF) -#define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) -#define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) +#define AO_RADIO_MODE_PACKET_TX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) +#define AO_RADIO_MODE_PACKET_RX (AO_RADIO_MODE_BITS_PACKET | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_RX) +#define AO_RADIO_MODE_RDF (AO_RADIO_MODE_BITS_RDF | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) +#define AO_RADIO_MODE_APRS_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) +#define AO_RADIO_MODE_APRS_LAST_BUF (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_BUF) +#define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) +#define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF) static void _ao_radio_set_regs(const uint16_t *regs, int nreg) @@ -596,17 +599,20 @@ ao_radio_set_mode(uint16_t new_mode) } } - if (changes & AO_RADIO_MODE_BITS_PACKET_TX) - ao_radio_set_regs(packet_tx_setup); - - if (changes & AO_RADIO_MODE_BITS_TX_BUF) + if (changes & AO_RADIO_MODE_BITS_TX_BUF) { ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_TXFIFO_THR); + ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH); + } - if (changes & AO_RADIO_MODE_BITS_TX_FINISH) - ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_RX0TX1_CFG); + if (changes & AO_RADIO_MODE_BITS_TX_FINISH) { + ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_PKT_SYNC_RXTX); + ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH); + } - if (changes & AO_RADIO_MODE_BITS_PACKET_RX) - ao_radio_set_regs(packet_rx_setup); + if (changes & AO_RADIO_MODE_BITS_RX) { + ao_radio_reg_write(AO_CC1200_INT_GPIO_IOCFG, CC1200_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP); + ao_exti_set_mode(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH); + } if (changes & AO_RADIO_MODE_BITS_RDF) ao_radio_set_regs(rdf_setup); @@ -635,12 +641,14 @@ static uint8_t ao_radio_configured = 0; static void ao_radio_setup(void) { -// ao_radio_strobe(CC1200_SRES); + ao_radio_strobe(CC1200_SRES); ao_radio_set_regs(radio_setup); ao_radio_mode = 0; + ao_radio_idle(); + ao_config_get(); ao_radio_configured = 1; @@ -672,6 +680,7 @@ ao_radio_get(uint8_t len) ao_radio_reg_write(CC1200_FREQ1, ao_config.radio_setting >> 8); ao_radio_reg_write(CC1200_FREQ0, ao_config.radio_setting); last_radio_setting = ao_config.radio_setting; + ao_radio_strobe(CC1200_SCAL); } if (ao_config.radio_rate != last_radio_rate) { ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET; @@ -682,6 +691,43 @@ ao_radio_get(uint8_t len) #define ao_radio_put() ao_mutex_put(&ao_radio_mutex) +static inline uint8_t +ao_radio_state(void) +{ + return (ao_radio_status() >> CC1200_STATUS_STATE) & CC1200_STATUS_STATE_MASK; +} + +#if CC1200_DEBUG +void +ao_radio_show_state(char *where) +{ + printf("%s: state %d len %d rxbytes %d\n", + where, ao_radio_state(), + ao_radio_reg_read(CC1200_PKT_LEN), + ao_radio_reg_read(CC1200_NUM_RXBYTES)); +} +#else +#define ao_radio_show_state(where) +#endif + +/* Wait for the radio to signal an interrupt + */ +static void +ao_radio_wait_isr(uint16_t timeout) +{ + if (timeout) + ao_alarm(timeout); + + ao_arch_block_interrupts(); + while (!ao_radio_wake && !ao_radio_abort) + if (ao_sleep(&ao_radio_wake)) + ao_radio_abort = 1; + ao_arch_release_interrupts(); + + if (timeout) + ao_clear_alarm(); +} + static void ao_rdf_start(uint8_t len) { @@ -690,20 +736,15 @@ ao_rdf_start(uint8_t len) ao_radio_set_mode(AO_RADIO_MODE_RDF); ao_radio_wake = 0; - } static void -ao_rdf_run(void) +ao_radio_run(void) { + ao_radio_wake = 0; + ao_radio_abort = 0; ao_radio_start_tx(); - - ao_arch_block_interrupts(); - while (!ao_radio_wake && !ao_radio_abort && !ao_radio_mcu_wake) - ao_sleep(&ao_radio_wake); - ao_arch_release_interrupts(); - if (ao_radio_mcu_wake) - ao_radio_check_marc_status(); + ao_radio_wait_isr(0); if (!ao_radio_wake) ao_radio_idle(); ao_radio_put(); @@ -716,7 +757,7 @@ ao_radio_rdf(void) ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN); - ao_rdf_run(); + ao_radio_run(); } void @@ -738,7 +779,7 @@ ao_radio_continuity(uint8_t c) ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN); status = ao_radio_fifo_write_stop(status); (void) status; - ao_rdf_run(); + ao_radio_run(); } void @@ -794,29 +835,18 @@ ao_radio_test_cmd(void) } } -static void -ao_radio_wait_isr(uint16_t timeout) -{ - if (timeout) - ao_alarm(timeout); - ao_arch_block_interrupts(); - while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort) - if (ao_sleep(&ao_radio_wake)) - ao_radio_abort = 1; - ao_arch_release_interrupts(); - if (timeout) - ao_clear_alarm(); - if (ao_radio_mcu_wake) - ao_radio_check_marc_status(); -} - void ao_radio_send(const void *d, uint8_t size) { - (void) d; - (void) size; + ao_radio_get(size); + ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX); + + ao_radio_fifo_write(d, size); + + ao_radio_run(); } + #define AO_RADIO_LOTS 64 void @@ -829,6 +859,7 @@ ao_radio_send_aprs(ao_radio_fill_func fill) uint8_t started = 0; uint8_t fifo_space; + ao_radio_abort = 0; ao_radio_get(0xff); fifo_space = CC1200_FIFO_SIZE; while (!done) { @@ -837,6 +868,9 @@ ao_radio_send_aprs(ao_radio_fill_func fill) done = 1; cnt = -cnt; } +#if CC1200_APRS_TRACE + printf("APRS fill %d bytes done %d\n", cnt, done); +#endif total += cnt; /* At the last buffer, set the total length */ @@ -849,8 +883,11 @@ ao_radio_send_aprs(ao_radio_fill_func fill) /* Wait for some space in the fifo */ while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) { +#if CC1200_APRS_TRACE + printf("APRS space %d cnt %d\n", fifo_space, cnt); flush(); +#endif ao_radio_wake = 0; - ao_radio_wait_isr(0); + ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); } if (ao_radio_abort) break; @@ -867,33 +904,194 @@ ao_radio_send_aprs(ao_radio_fill_func fill) } else ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); + ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); + ao_radio_fifo_write(b, this_len); b += this_len; - +#if CC1200_APRS_TRACE + printf("APRS write fifo %d space now %d\n", this_len, ao_radio_tx_fifo_space()); +#endif if (!started) { - ao_radio_start_tx(); +#if CC1200_APRS_TRACE + printf("APRS start\n"); +#endif + ao_radio_strobe(CC1200_STX); +#if CC1200_APRS_TRACE + { int t; + for (t = 0; t < 20; t++) { + uint8_t status = ao_radio_status(); + uint8_t space = ao_radio_tx_fifo_space(); + printf ("status: %02x fifo %d\n", status, space); + if ((status >> 4) == 2) + break; + ao_delay(AO_MS_TO_TICKS(0)); + } + } +#endif started = 1; - } else - ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); + } } if (ao_radio_abort) { ao_radio_idle(); break; } - /* Wait for the transmitter to go idle */ - ao_radio_wake = 0; - ao_radio_wait_isr(0); } + /* Wait for the transmitter to go idle */ + ao_radio_wake = 0; +#if CC1200_APRS_TRACE + printf("APRS wait idle\n"); flush(); +#endif + ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); +#if CC1200_APRS_TRACE + printf("APRS abort %d\n", ao_radio_abort); +#endif ao_radio_put(); } +#if 0 +static uint8_t +ao_radio_marc_state(void) +{ + return ao_radio_reg_read(CC1200_MARCSTATE); +} + +static uint8_t +ao_radio_modem_status1(void) +{ + return ao_radio_reg_read(CC1200_MODEM_STATUS1); +} + +static uint8_t +ao_radio_modem_status0(void) +{ + return ao_radio_reg_read(CC1200_MODEM_STATUS0); +} + +struct ao_radio_state { + char where[4]; + uint8_t marc_state; + uint8_t marc_status1; + uint8_t marc_status0; + uint8_t modem_status1; + uint8_t modem_status0; +}; + +static void +ao_radio_fill_state(char *where, struct ao_radio_state *s) +{ + strcpy(s->where, where); + s->marc_state = ao_radio_marc_state(); + s->marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1); + s->marc_status0 = ao_radio_reg_read(CC1200_MARC_STATUS0); + s->modem_status1 = ao_radio_modem_status1(); + s->modem_status0 = ao_radio_modem_status0(); +} + +static void +ao_radio_dump_state(struct ao_radio_state *s) +{ + printf ("%s: marc %2x marc1 %2x marc0 %2x modem1 %2x modem0 %2x\n", + s->where, s->marc_state, s->marc_status1, s->marc_status0, s->modem_status1, s->modem_status0); +} +#endif + uint8_t ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) { - (void) d; - (void) size; - (void) timeout; - return 0; + uint8_t success = 0; + + ao_radio_abort = 0; + ao_radio_get(size - 2); + ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX); + ao_radio_wake = 0; + ao_radio_start_rx(); + + while (!ao_radio_abort) { + ao_radio_wait_isr(timeout); + if (ao_radio_wake) { + uint8_t marc_status1 = ao_radio_reg_read(CC1200_MARC_STATUS1); + + /* Check the receiver status to see what happened + */ + switch (marc_status1) { + case CC1200_MARC_STATUS1_RX_FINISHED: + case CC1200_MARC_STATUS1_ADDRESS: + case CC1200_MARC_STATUS1_CRC: + /* Normal return, go fetch the bytes from the FIFO + * and give them back to the caller + */ + success = 1; + break; + case CC1200_MARC_STATUS1_RX_TIMEOUT: + case CC1200_MARC_STATUS1_RX_TERMINATION: + case CC1200_MARC_STATUS1_EWOR_SYNC_LOST: + case CC1200_MARC_STATUS1_MAXIMUM_LENGTH: + case CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW: + case CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW: + /* Something weird happened; reset the radio and + * return failure + */ + success = 0; + break; + default: + /* some other status; go wait for the radio to do something useful + */ + continue; + } + break; + } else { + uint8_t modem_status1 = ao_radio_reg_read(CC1200_MODEM_STATUS1); + + /* Check to see if the packet header has been seen, in which case we'll + * want to keep waiting for the rest of the packet to appear + */ + if (modem_status1 & (1 << CC1200_MODEM_STATUS1_SYNC_FOUND)) + { + ao_radio_abort = 0; + + /* Set a timeout based on the packet length so that we make sure to + * wait long enough to receive the whole thing. + * + * timeout = bits * FEC expansion / rate + */ + switch (ao_config.radio_rate) { + default: + case AO_RADIO_RATE_38400: + timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 384) + 1; + break; + case AO_RADIO_RATE_9600: + timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 96) + 1; + break; + case AO_RADIO_RATE_2400: + timeout = AO_MS_TO_TICKS(size * (8 * 2 * 10) / 24) + 1; + break; + } + } + } + } + + if (success) { + int8_t rssi; + uint8_t status; + + status = ao_radio_fifo_read(d, size); + (void) status; + rssi = ((int8_t *) d)[size - 2]; + ao_radio_rssi = rssi; + + /* Bound it to the representable range */ + if (rssi > -11) + rssi = -11; + + /* Write it back to the packet */ + ((int8_t *) d)[size-2] = AO_RADIO_FROM_RSSI(rssi); + } else { + ao_radio_idle(); + ao_radio_rssi = 0; + } + + ao_radio_put(); + return success; } @@ -932,6 +1130,7 @@ static const struct ao_cc1200_reg ao_cc1200_reg[] = { { .addr = CC1200_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" }, { .addr = CC1200_IQIC, .name = "IQIC" }, { .addr = CC1200_CHAN_BW, .name = "CHAN_BW" }, + { .addr = CC1200_MDMCFG2, .name = "MDMCFG2" }, { .addr = CC1200_MDMCFG1, .name = "MDMCFG1" }, { .addr = CC1200_MDMCFG0, .name = "MDMCFG0" }, { .addr = CC1200_SYMBOL_RATE2, .name = "SYMBOL_RATE2" }, @@ -1064,8 +1263,8 @@ static const struct ao_cc1200_reg ao_cc1200_reg[] = { { .addr = CC1200_PARTNUMBER, .name = "PARTNUMBER" }, { .addr = CC1200_PARTVERSION, .name = "PARTVERSION" }, { .addr = CC1200_SERIAL_STATUS, .name = "SERIAL_STATUS" }, - { .addr = CC1200_RX_STATUS, .name = "RX_STATUS" }, - { .addr = CC1200_TX_STATUS, .name = "TX_STATUS" }, + { .addr = CC1200_MODEM_STATUS1, .name = "MODEM_STATUS1" }, + { .addr = CC1200_MODEM_STATUS0, .name = "MODEM_STATUS0" }, { .addr = CC1200_MARC_STATUS1, .name = "MARC_STATUS1" }, { .addr = CC1200_MARC_STATUS0, .name = "MARC_STATUS0" }, { .addr = CC1200_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" }, @@ -1091,11 +1290,17 @@ static const struct ao_cc1200_reg ao_cc1200_reg[] = { #define AO_NUM_CC1200_REG (sizeof ao_cc1200_reg / sizeof ao_cc1200_reg[0]) +static uint8_t +ao_radio_get_marc_status(void) +{ + return ao_radio_reg_read(CC1200_MARC_STATUS1); +} + static void ao_radio_show(void) { - uint8_t status = ao_radio_status(); + uint8_t status; unsigned int i; - ao_radio_get(0xff); + ao_mutex_get(&ao_radio_mutex); status = ao_radio_status(); printf ("Status: %02x\n", status); printf ("CHIP_RDY: %d\n", (status >> CC1200_STATUS_CHIP_RDY) & 1); @@ -1141,6 +1346,8 @@ ao_radio_test_recv(void) printf (" RSSI %d", AO_RSSI_FROM_RADIO(bytes[32])); for (b = 0; b < 32; b++) printf (" %02x", bytes[b]); + + printf (" RSSI %02x LQI %02x", bytes[32], bytes[33]); printf ("\n"); } } @@ -1151,12 +1358,15 @@ ao_radio_test_recv(void) static void ao_radio_aprs(void) { +#if PACKET_HAS_SLAVE ao_packet_slave_stop(); +#endif ao_aprs_send(); } #endif #endif +#if CC1200_LOW_LEVEL_DEBUG static void ao_radio_strobe_test(void) { @@ -1204,6 +1414,7 @@ ao_radio_read_test(void) data = ao_radio_reg_read(addr); printf ("Read %04x = %02x\n", addr, data); } +#endif static const struct ao_cmds ao_radio_cmds[] = { { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" }, @@ -1216,9 +1427,11 @@ static const struct ao_cmds ao_radio_cmds[] = { { ao_radio_packet, "p\0Send a test packet" }, { ao_radio_test_recv, "q\0Recv a test packet" }, #endif - { ao_radio_strobe_test, "S \0Strobe radio" }, +#if CC1200_LOW_LEVEL_DEBUG + { ao_radio_strobe_test, "A \0Strobe radio" }, { ao_radio_write_test, "W \0Write radio reg" }, - { ao_radio_read_test, "R \0Read radio reg" }, + { ao_radio_read_test, "B \0Read radio reg" }, +#endif { 0, NULL } }; diff --git a/src/drivers/ao_cc1200.h b/src/drivers/ao_cc1200.h index 987f9bda..b04775fd 100644 --- a/src/drivers/ao_cc1200.h +++ b/src/drivers/ao_cc1200.h @@ -27,7 +27,7 @@ #define CC1200_IOCFG_GPIO_INV 6 #define CC1200_IOCFG_GPIO_CFG 0 #define CC1200_IOCFG_GPIO_CFG_RXFIFO_THR 0 -#define CC1200_IOCFG_GPIO_CFG_RXFIFO_THR_PKT 1 +#define CC1200_IOCFG_GPIO_CFG_RXFIFO_THR_PKT 1 #define CC1200_IOCFG_GPIO_CFG_TXFIFO_THR 2 #define CC1200_IOCFG_GPIO_CFG_TXFIFO_THR_PKT 3 #define CC1200_IOCFG_GPIO_CFG_RXFIFO_OVERFLOW 4 @@ -101,7 +101,6 @@ #define CC1200_IOCFG_GPIO_CFG_EXT_OSC_EN 60 #define CC1200_IOCFG_GPIO_CFG_MASK 0x3f -#define CC1200_IOCFG3 0x00 #define CC1200_IOCFG2 0x01 #define CC1200_IOCFG1 0x02 #define CC1200_IOCFG0 0x03 @@ -141,21 +140,21 @@ #define CC1200_DEVIATION_M 0x0a #define CC1200_MODCFG_DEV_E 0x0b -#define CC1200_MODCFG_DEV_E_MODEM_MODE 6 +#define CC1200_MODCFG_DEV_E_MODEM_MODE 6 #define CC1200_MODCFG_DEV_E_MODEM_MODE_NORMAL 0 #define CC1200_MODCFG_DEV_E_MODEM_MODE_DSSS_REPEAT 1 #define CC1200_MODCFG_DEV_E_MODEM_MODE_DSSS_PN 2 #define CC1200_MODCFG_DEV_E_MODEM_MODE_CARRIER_SENSE 3 #define CC1200_MODCFG_DEV_E_MODEM_MODE_MASK 3 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT 3 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT_2_FSK 0 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK 1 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT_ASK_OOK 3 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT_4_FSK 4 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT_4_GFSK 5 -#define CC1200_MODCFG_DEV_E_MOD_FORMAT_MASK 7 -#define CC1200_MODCFG_DEV_E_DEV_E 0 -#define CC1200_MODCFG_DEV_E_DEV_E_MASK 7 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT 3 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT_2_FSK 0 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT_2_GFSK 1 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT_ASK_OOK 3 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT_4_FSK 4 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT_4_GFSK 5 +#define CC1200_MODCFG_DEV_E_MOD_FORMAT_MASK 7 +#define CC1200_MODCFG_DEV_E_DEV_E 0 +#define CC1200_MODCFG_DEV_E_DEV_E_MASK 7 #define CC1200_DCFILT_CFG 0x0c #define CC1200_PREAMBLE_CFG1 0x0d @@ -226,10 +225,10 @@ #define CC1200_MDMCFG0_VITERBI_EN 2 #define CC1200_SYMBOL_RATE2 0x13 -#define CC1200_SYMBOL_RATE2_DATARATE_E 4 -#define CC1200_SYMBOL_RATE2_DATARATE_E_MASK 0xf -#define CC1200_SYMBOL_RATE2_DATARATE_M_19_16 0 -#define CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK 0xf +#define CC1200_SYMBOL_RATE2_DATARATE_E 4 +#define CC1200_SYMBOL_RATE2_DATARATE_E_MASK 0xf +#define CC1200_SYMBOL_RATE2_DATARATE_M_19_16 0 +#define CC1200_SYMBOL_RATE2_DATARATE_M_19_16_MASK 0xf #define CC1200_SYMBOL_RATE1 0x14 #define CC1200_SYMBOL_RATE0 0x15 @@ -338,6 +337,8 @@ #define CC1200_WOR_EVENT0_LSB 0x24 #define CC1200_RXDCM_TIME 0x25 #define CC1200_PKT_CFG2 0x26 +#define CC1200_PKT_CFG2_BYTE_SWAP_EN 6 +#define CC1200_PKT_CFG2_FG_MODE_EN 5 #define CC1200_PKT_CFG2_CCA_MODE 2 #define CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR 0 #define CC1200_PKT_CFG2_CCA_MODE_RSSI_THRESHOLD 1 @@ -353,19 +354,20 @@ #define CC1200_PKT_CFG2_PKT_FORMAT_MASK 3 #define CC1200_PKT_CFG1 0x27 +#define CC1200_PKT_CFG1_FEC_EN 7 #define CC1200_PKT_CFG1_WHITE_DATA 6 -#define CC1200_PKT_CFG1_ADDR_CHECK_CFG 4 +#define CC1200_PKT_CFG1_PN9_SWAP_EN 5 +#define CC1200_PKT_CFG1_ADDR_CHECK_CFG 3 #define CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE 0 #define CC1200_PKT_CFG1_ADDR_CHECK_CFG_CHECK 1 #define CC1200_PKT_CFG1_ADDR_CHECK_CFG_00_BROADCAST 2 #define CC1200_PKT_CFG1_ADDR_CHECK_CFG_00_FF_BROADCAST 3 #define CC1200_PKT_CFG1_ADDR_CHECK_CFG_MASK 3 -#define CC1200_PKT_CFG1_CRC_CFG 2 +#define CC1200_PKT_CFG1_CRC_CFG 1 #define CC1200_PKT_CFG1_CRC_CFG_DISABLED 0 #define CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES 1 #define CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ZEROS 2 #define CC1200_PKT_CFG1_CRC_CFG_MASK 3 -#define CC1200_PKT_CFG1_BYTE_SWAP_EN 1 #define CC1200_PKT_CFG1_APPEND_STATUS 0 #define CC1200_PKT_CFG0 0x28 @@ -382,13 +384,29 @@ #define CC1200_PKT_CFG0_UART_SWAP_EN 0 #define CC1200_RFEND_CFG1 0x29 +#define CC1200_RFEND_CFG1_RXOFF_MODE 4 +#define CC1200_RFEND_CFG1_RXOFF_MODE_IDLE 0 +#define CC1200_RFEND_CFG1_RXOFF_MODE_FSTXON 1 +#define CC1200_RFEND_CFG1_RXOFF_MODE_TX 2 +#define CC1200_RFEND_CFG1_RXOFF_MODE_RX 3 +#define CC1200_RFEND_CFG1_RX_TIME 1 +#define CC1200_RFEND_CFG1_RX_TIME_INFINITE 7 +#define CC1200_RFEND_CFG1_RX_TIME_QUAL 0 #define CC1200_RFEND_CFG0 0x2a +#define CC1200_RFEND_CFG0_CAL_END_WAKE_UP_EN 6 +#define CC1200_RFEND_CFG0_TXOFF_MODE 4 +#define CC1200_RFEND_CFG0_TXOFF_MODE_IDLE 0 +#define CC1200_RFEND_CFG0_TXOFF_MODE_FSTXON 1 +#define CC1200_RFEND_CFG0_TXOFF_MODE_TX 2 +#define CC1200_RFEND_CFG0_TXOFF_MODE_RX 3 +#define CC1200_RFEND_CFG0_TERM_ON_BAD_PACKET_EN 3 +#define CC1200_RFEND_CFG0_ANT_DIV_RX_TERM_CFG 0 #define CC1200_PA_CFG1 0x2b #define CC1200_PA_CFG0 0x2c #define CC1200_ASK_CFG 0x2d #define CC1200_PKT_LEN 0x2e -#define CC1200_EXTENDED 0x2f +#define CC1200_EXTENDED 0x2f /* Command strobes */ #define CC1200_SRES 0x30 @@ -424,10 +442,25 @@ #define CC1200_ECG_CFG (CC1200_EXTENDED_BIT | 0x04) #define CC1200_MDMCFG2 (CC1200_EXTENDED_BIT | 0x05) -# define CC1200_MDMCFG2_ASK_SHAPE 6 -# define CC1200_MDMCFG2_SYMBOL_MAP_CFG 4 -# define CC1200_MDMCFG2_UPSAMPLER_P 1 -# define CC1200_MDMCFG2_CFM_DATA_EN 0 +#define CC1200_MDMCFG2_ASK_SHAPE 6 +#define CC1200_MDMCFG2_ASK_SHAPE_8 0 +#define CC1200_MDMCFG2_ASK_SHAPE_16 1 +#define CC1200_MDMCFG2_ASK_SHAPE_32 2 +#define CC1200_MDMCFG2_ASK_SHAPE_128 3 +#define CC1200_MDMCFG2_SYMBOL_MAP_CFG 4 +#define CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 0 +#define CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_1 1 +#define CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_2 2 +#define CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_3 3 +#define CC1200_MDMCFG2_UPSAMPLER_P 1 +#define CC1200_MDMCFG2_UPSAMPLER_P_1 0 +#define CC1200_MDMCFG2_UPSAMPLER_P_2 1 +#define CC1200_MDMCFG2_UPSAMPLER_P_4 2 +#define CC1200_MDMCFG2_UPSAMPLER_P_8 3 +#define CC1200_MDMCFG2_UPSAMPLER_P_16 4 +#define CC1200_MDMCFG2_UPSAMPLER_P_32 5 +#define CC1200_MDMCFG2_UPSAMPLER_P_64 6 +#define CC1200_MDMCFG2_CFM_DATA_EN 0 #define CC1200_EXT_CTRL (CC1200_EXTENDED_BIT | 0x06) #define CC1200_RCCAL_FINE (CC1200_EXTENDED_BIT | 0x07) @@ -527,23 +560,39 @@ #define CC1200_PARTNUMBER (CC1200_EXTENDED_BIT | 0x8f) #define CC1200_PARTVERSION (CC1200_EXTENDED_BIT | 0x90) #define CC1200_SERIAL_STATUS (CC1200_EXTENDED_BIT | 0x91) -#define CC1200_RX_STATUS (CC1200_EXTENDED_BIT | 0x92) -#define CC1200_TX_STATUS (CC1200_EXTENDED_BIT | 0x93) +#define CC1200_MODEM_STATUS1 (CC1200_EXTENDED_BIT | 0x92) +#define CC1200_MODEM_STATUS1_SYNC_FOUND 7 +#define CC1200_MODEM_STATUS1_RXFIFO_FULL 6 +#define CC1200_MODEM_STATUS1_RXFIFO_THR 5 +#define CC1200_MODEM_STATUS1_RXFIFO_EMPTY 4 +#define CC1200_MODEM_STATUS1_RXFIFO_OVERFLOW 3 +#define CC1200_MODEM_STATUS1_RXFIFO_UNDERFLOW 2 +#define CC1200_MODEM_STATUS1_PQT_REACHED 1 +#define CC1200_MODEM_STATUS1_PQT_VALID 0 + +#define CC1200_MODEM_STATUS0 (CC1200_EXTENDED_BIT | 0x93) +#define CC1200_MODEM_STATUS0_FEC_RX_OVERFLOW 6 +#define CC1200_MODEM_STATUS0_SYNC_SENT 4 +#define CC1200_MODEM_STATUS0_TXFIFO_FULL 3 +#define CC1200_MODEM_STATUS0_TXFIFO_THR 2 +#define CC1200_MODEM_STATUS0_TXFIFO_OVERFLOW 1 +#define CC1200_MODEM_STATUS0_TXFIFO_UNDERFLOW 0 + #define CC1200_MARC_STATUS1 (CC1200_EXTENDED_BIT | 0x94) -# define CC1200_MARC_STATUS1_NO_FAILURE 0 -# define CC1200_MARC_STATUS1_RX_TIMEOUT 1 -# define CC1200_MARC_STATUS1_RX_TERMINATION 2 -# define CC1200_MARC_STATUS1_EWOR_SYNC_LOST 3 -# define CC1200_MARC_STATUS1_MAXIMUM_LENGTH 4 -# define CC1200_MARC_STATUS1_ADDRESS 5 -# define CC1200_MARC_STATUS1_CRC 6 -# define CC1200_MARC_STATUS1_TX_FIFO_OVERFLOW 7 -# define CC1200_MARC_STATUS1_TX_FIFO_UNDERFLOW 8 -# define CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW 9 -# define CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW 10 -# define CC1200_MARC_STATUS1_TX_ON_CCA_FAILED 11 -# define CC1200_MARC_STATUS1_TX_FINISHED 0x40 -# define CC1200_MARC_STATUS1_RX_FINISHED 0x80 +#define CC1200_MARC_STATUS1_NO_FAILURE 0 +#define CC1200_MARC_STATUS1_RX_TIMEOUT 1 +#define CC1200_MARC_STATUS1_RX_TERMINATION 2 +#define CC1200_MARC_STATUS1_EWOR_SYNC_LOST 3 +#define CC1200_MARC_STATUS1_MAXIMUM_LENGTH 4 +#define CC1200_MARC_STATUS1_ADDRESS 5 +#define CC1200_MARC_STATUS1_CRC 6 +#define CC1200_MARC_STATUS1_TX_FIFO_OVERFLOW 7 +#define CC1200_MARC_STATUS1_TX_FIFO_UNDERFLOW 8 +#define CC1200_MARC_STATUS1_RX_FIFO_OVERFLOW 9 +#define CC1200_MARC_STATUS1_RX_FIFO_UNDERFLOW 10 +#define CC1200_MARC_STATUS1_TX_ON_CCA_FAILED 11 +#define CC1200_MARC_STATUS1_TX_FINISHED 0x40 +#define CC1200_MARC_STATUS1_RX_FINISHED 0x80 #define CC1200_MARC_STATUS0 (CC1200_EXTENDED_BIT | 0x95) #define CC1200_PA_IFAMP_TEST (CC1200_EXTENDED_BIT | 0x96) #define CC1200_FSRF_TEST (CC1200_EXTENDED_BIT | 0x97) diff --git a/src/drivers/ao_cc1200_CC1200.h b/src/drivers/ao_cc1200_CC1200.h index 670e89ef..c5497196 100644 --- a/src/drivers/ao_cc1200_CC1200.h +++ b/src/drivers/ao_cc1200_CC1200.h @@ -7,34 +7,100 @@ * ***************************************************************/ +/* + * Values affecting receive sensitivity: + * + * + * PQT - sets how good the preamble needs to look before + * we start looking for a sync word + * SYNC_THR - sets how good the sync needs to be before we + * start decoding a packet + */ + +/* Values depending on data rate + * + * DCFILT_BW_SETTLE + * DCFILT_BW + */ + +#ifndef AO_CC1200_AGC_GAIN_ADJUST +#define AO_CC1200_AGC_GAIN_ADJUST -81 +#endif CC1200_IOCFG2, 0x06, /* GPIO2 IO Pin Configuration */ - CC1200_SYNC1, 0x6e, /* Sync Word Configuration [15:8] */ - CC1200_SYNC0, 0x4e, /* Sync Word Configuration [7:0] */ - CC1200_SYNC_CFG1, 0xea, /* Sync Word Detection Configuration Reg. 1 */ + CC1200_SYNC3, 0xD3, /* Sync Word Configuration [23:16] */ + CC1200_SYNC2, 0x91, /* Sync Word Configuration [23:16] */ + CC1200_SYNC1, 0xD3, /* Sync Word Configuration [15:8] */ + CC1200_SYNC0, 0x91, /* Sync Word Configuration [7:0] */ + CC1200_SYNC_CFG1, /* Sync Word Detection Configuration Reg. 1 */ + ((CC1200_SYNC_CFG1_SYNC_MODE_16_BITS << CC1200_SYNC_CFG1_SYNC_MODE) | + (11 << CC1200_SYNC_CFG1_SYNC_THR)), + CC1200_SYNC_CFG0, /* Sync Word Detection Configuration Reg. 0 */ + ((1 << CC1200_SYNC_CFG0_AUTO_CLEAR) | + (0 << CC1200_SYNC_CFG0_RX_CONFIG_LIMITATION) | + (1 << CC1200_SYNC_CFG0_PQT_GATING_EN) | + (0 << CC1200_SYNC_CFG0_EXT_SYNC_DETECT) | + (CC1200_SYNC_CFG0_SYNC_STRICT_SYNC_CHECK_DISABLED << CC1200_SYNC_CFG0_SYNC_STRICT_SYNC_CHECK)), CC1200_DEVIATION_M, 0x50, /* Frequency Deviation Configuration */ CC1200_DCFILT_CFG, 0x5d, /* Digital DC Removal Configuration */ - CC1200_PREAMBLE_CFG0, 0x8a, /* Preamble Detection Configuration Reg. 0 */ + CC1200_PREAMBLE_CFG0, /* Preamble Detection Configuration Reg. 0 */ + ((1 << CC1200_PREAMBLE_CFG0_PQT_EN) | + (CC1200_PREAMBLE_CFG0_PQT_VALID_TIMEOUT_11 << CC1200_PREAMBLE_CFG0_PQT_VALID_TIMEOUT) | + (15 << CC1200_PREAMBLE_CFG0_PQT)), CC1200_IQIC, 0xcb, /* Digital Image Channel Compensation Configuration */ CC1200_CHAN_BW, 0x11, /* Channel Filter Configuration */ CC1200_MDMCFG1, 0x40, /* General Modem Parameter Configuration Reg. 1 */ CC1200_MDMCFG0, 0x05, /* General Modem Parameter Configuration Reg. 0 */ CC1200_SYMBOL_RATE2, 0x93, /* Symbol Rate Configuration Exponent and Mantissa [1.. */ - CC1200_AGC_REF, 0x37, /* AGC Reference Level Configuration */ + CC1200_AGC_REF, 0x27, /* AGC Reference Level Configuration */ CC1200_AGC_CS_THR, 0xec, /* Carrier Sense Threshold Configuration */ + CC1200_AGC_GAIN_ADJUST, /* RSSI adjustment */ + AO_CC1200_AGC_GAIN_ADJUST, CC1200_AGC_CFG1, 0x51, /* Automatic Gain Control Configuration Reg. 1 */ CC1200_AGC_CFG0, 0x87, /* Automatic Gain Control Configuration Reg. 0 */ - CC1200_FIFO_CFG, 0x00, /* FIFO Configuration */ - CC1200_FS_CFG, 0x14, /* Frequency Synthesizer Configuration */ - CC1200_PKT_CFG2, 0x20, /* Packet Configuration Reg. 2 */ - CC1200_PKT_CFG1, 0xc3, /* Packet Configuration Reg. 1 */ - CC1200_PKT_CFG0, 0x20, /* Packet Configuration Reg. 0 */ + CC1200_FIFO_CFG, 0x40, /* FIFO Configuration */ + CC1200_SETTLING_CFG, /* Frequency Synthesizer Calibration and Settling Configuration */ + ((CC1200_SETTLING_CFG_FS_AUTOCAL_EVERY_4TH_TIME << CC1200_SETTLING_CFG_FS_AUTOCAL) | + (CC1200_SETTLING_CFG_LOCK_TIME_75_30 << CC1200_SETTLING_CFG_LOCK_TIME) | + (CC1200_SETTLING_CFG_FSREG_TIME_60 << CC1200_SETTLING_CFG_FSREG_TIME)), + CC1200_FS_CFG, /* Frequency Synthesizer Configuration */ + ((1 << CC1200_FS_CFG_LOCK_EN) | + (CC1200_FS_CFG_FSD_BANDSELECT_410_480 << CC1200_FS_CFG_FSD_BANDSELECT)), + CC1200_PKT_CFG2, /* Packet Configuration Reg. 2 */ + ((0 << CC1200_PKT_CFG2_FG_MODE_EN) | + (CC1200_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1200_PKT_CFG2_CCA_MODE) | + (CC1200_PKT_CFG2_PKT_FORMAT_NORMAL << CC1200_PKT_CFG2_PKT_FORMAT)), + CC1200_PKT_CFG1, /* Packet Configuration Reg. 1 */ + ((1 << CC1200_PKT_CFG1_FEC_EN) | + (1 << CC1200_PKT_CFG1_WHITE_DATA) | + (0 << CC1200_PKT_CFG1_PN9_SWAP_EN) | + (CC1200_PKT_CFG1_ADDR_CHECK_CFG_NONE << CC1200_PKT_CFG1_ADDR_CHECK_CFG) | + (CC1200_PKT_CFG1_CRC_CFG_CRC16_INIT_ONES << CC1200_PKT_CFG1_CRC_CFG) | + (1 << CC1200_PKT_CFG1_APPEND_STATUS)), + CC1200_PKT_CFG0, /* Packet Configuration Reg. 0 */ + ((CC1200_PKT_CFG0_LENGTH_CONFIG_FIXED << CC1200_PKT_CFG0_LENGTH_CONFIG) | + (0 << CC1200_PKT_CFG0_PKG_BIT_LEN) | + (0 << CC1200_PKT_CFG0_UART_MODE_EN) | + (0 << CC1200_PKT_CFG0_UART_SWAP_EN)), + CC1200_RFEND_CFG1, /* RFEND Configuration Reg. 1 */ + ((CC1200_RFEND_CFG1_RXOFF_MODE_IDLE << CC1200_RFEND_CFG1_RXOFF_MODE) | + (CC1200_RFEND_CFG1_RX_TIME_INFINITE << CC1200_RFEND_CFG1_RX_TIME) | + (0 << CC1200_RFEND_CFG1_RX_TIME_QUAL)), + CC1200_RFEND_CFG0, /* RFEND Configuration Reg. 0 */ + ((0 << CC1200_RFEND_CFG0_CAL_END_WAKE_UP_EN) | + (CC1200_RFEND_CFG0_TXOFF_MODE_IDLE << CC1200_RFEND_CFG0_TXOFF_MODE) | + (1 << CC1200_RFEND_CFG0_TERM_ON_BAD_PACKET_EN) | + (0 << CC1200_RFEND_CFG0_ANT_DIV_RX_TERM_CFG)), CC1200_PA_CFG1, 0x3f, /* Power Amplifier Configuration Reg. 1 */ CC1200_PA_CFG0, 0x53, /* Power Amplifier Configuration Reg. 0 */ CC1200_PKT_LEN, 0xff, /* Packet Length Configuration */ CC1200_IF_MIX_CFG, 0x1c, /* IF Mix Configuration */ CC1200_FREQOFF_CFG, 0x22, /* Frequency Offset Correction Configuration */ - CC1200_MDMCFG2, 0x0c, /* General Modem Parameter Configuration Reg. 2 */ + CC1200_MDMCFG2, /* General Modem Parameter Configuration Reg. 2 */ + ((CC1200_MDMCFG2_ASK_SHAPE_8 << CC1200_MDMCFG2_ASK_SHAPE) | + (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | + (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) | + (0 << CC1200_MDMCFG2_CFM_DATA_EN)), CC1200_FREQ2, 0x6c, /* Frequency Configuration [23:16] */ CC1200_FREQ1, 0xa3, /* Frequency Configuration [15:8] */ CC1200_FREQ0, 0x33, /* Frequency Configuration [7:0] */ diff --git a/src/kernel/ao.h b/src/kernel/ao.h index ad5bbf8e..16d600aa 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -43,10 +43,6 @@ #define HAS_TASK 1 #endif -#ifndef AO_PORT_TYPE -#define AO_PORT_TYPE uint8_t -#endif - typedef AO_PORT_TYPE ao_port_t; #if HAS_TASK @@ -518,15 +514,9 @@ struct ao_telemetry_raw_recv { /* Set delay between telemetry reports (0 to disable) */ -#ifdef AO_SEND_ALL_BARO -#define AO_TELEMETRY_INTERVAL_PAD AO_MS_TO_TICKS(100) -#define AO_TELEMETRY_INTERVAL_FLIGHT AO_MS_TO_TICKS(100) -#define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(100) -#else #define AO_TELEMETRY_INTERVAL_PAD AO_MS_TO_TICKS(1000) #define AO_TELEMETRY_INTERVAL_FLIGHT AO_MS_TO_TICKS(100) #define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(1000) -#endif void ao_telemetry_reset_interval(void); @@ -662,6 +652,7 @@ union ao_monitor { extern __xdata union ao_monitor ao_monitor_ring[AO_MONITOR_RING]; #define ao_monitor_ring_next(n) (((n) + 1) & (AO_MONITOR_RING - 1)) +#define ao_monitor_ring_prev(n) (((n) - 1) & (AO_MONITOR_RING - 1)) extern __data uint8_t ao_monitoring; extern __data uint8_t ao_monitor_head; diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 6b8a1813..8dab7c42 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -557,10 +557,10 @@ ao_config_radio_rate_set(void) __reentrant } _ao_config_edit_start(); ao_config.radio_rate = ao_cmd_lex_i; + _ao_config_edit_finish(); #if HAS_TELEMETRY ao_telemetry_reset_interval(); #endif - _ao_config_edit_finish(); #if HAS_RADIO_RECV ao_radio_recv_abort(); #endif @@ -684,6 +684,9 @@ ao_config_radio_enable_set(void) __reentrant _ao_config_edit_start(); ao_config.radio_enable = ao_cmd_lex_i; _ao_config_edit_finish(); +#if HAS_TELEMETRY && HAS_RADIO_RATE + ao_telemetry_reset_interval(); +#endif } #endif /* HAS_RADIO */ @@ -735,6 +738,7 @@ ao_config_aprs_set(void) _ao_config_edit_start(); ao_config.aprs_interval = ao_cmd_lex_i; _ao_config_edit_finish(); + ao_telemetry_reset_interval(); } #endif /* HAS_APRS */ @@ -825,6 +829,9 @@ ao_config_tracker_set(void) ao_config.tracker_motion = m; ao_config.tracker_interval = i; _ao_config_edit_finish(); +#if HAS_TELEMETRY + ao_telemetry_reset_interval(); +#endif } #endif /* HAS_TRACKER */ diff --git a/src/kernel/ao_gps_print.c b/src/kernel/ao_gps_print.c index d26021da..6d9ee346 100644 --- a/src/kernel/ao_gps_print.c +++ b/src/kernel/ao_gps_print.c @@ -20,8 +20,8 @@ #endif #include "ao_telem.h" -#ifndef AO_TELEMETRY_LOCATION_ALTITUDE -#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#ifndef AO_GPS_ORIG_ALTITUDE +#define AO_GPS_ORIG_ALTITUDE(l) ((l)->altitude) #endif void @@ -46,7 +46,7 @@ ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant AO_TELEM_GPS_ALTITUDE " %d ", (long) gps_data->latitude, (long) gps_data->longitude, - AO_TELEMETRY_LOCATION_ALTITUDE(gps_data)); + AO_GPS_ORIG_ALTITUDE(gps_data)); if (gps_data->flags & AO_GPS_DATE_VALID) printf(AO_TELEM_GPS_YEAR " %d " diff --git a/src/kernel/ao_monitor.c b/src/kernel/ao_monitor.c index 2d75c41c..cba0d80a 100644 --- a/src/kernel/ao_monitor.c +++ b/src/kernel/ao_monitor.c @@ -94,9 +94,18 @@ __xdata struct ao_task ao_monitor_blink_task; void ao_monitor_blink(void) { +#ifdef AO_MONITOR_BAD + uint8_t *recv; +#endif for (;;) { ao_sleep(DATA_TO_XDATA(&ao_monitor_head)); - ao_led_for(AO_MONITOR_LED, AO_MS_TO_TICKS(100)); +#ifdef AO_MONITOR_BAD + recv = (uint8_t *) &ao_monitor_ring[ao_monitor_ring_prev(ao_monitor_head)]; + if (ao_monitoring && !(recv[ao_monitoring + 1] & AO_RADIO_STATUS_CRC_OK)) + ao_led_for(AO_MONITOR_BAD, AO_MS_TO_TICKS(100)); + else +#endif + ao_led_for(AO_MONITOR_LED, AO_MS_TO_TICKS(100)); } } #endif diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 27306a34..e2197f7a 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -19,19 +19,32 @@ #include "ao_log.h" #include "ao_product.h" -#ifndef HAS_RDF -#define HAS_RDF 1 -#endif - static __pdata uint16_t ao_telemetry_interval; #if HAS_RADIO_RATE static __xdata uint16_t ao_telemetry_desired_interval; #endif +/* TeleMetrum v1.0 just doesn't have enough space to + * manage the more complicated telemetry scheduling, so + * it loses the ability to disable telem/rdf separately + */ + +#if defined(TELEMETRUM_V_1_0) +#define SIMPLIFY +#endif + +#ifdef SIMPLIFY +#define ao_telemetry_time time +#define RDF_SPACE __pdata +#else +#define RDF_SPACE __xdata +static __pdata uint16_t ao_telemetry_time; +#endif + #if HAS_RDF -static __pdata uint8_t ao_rdf = 0; -static __pdata uint16_t ao_rdf_time; +static RDF_SPACE uint8_t ao_rdf = 0; +static RDF_SPACE uint16_t ao_rdf_time; #endif #if HAS_APRS @@ -120,7 +133,9 @@ ao_send_mega_sensor(void) telemetry.generic.tick = packet->tick; telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR; +#if HAS_MPU6000 telemetry.mega_sensor.orient = ao_sample_orient; +#endif telemetry.mega_sensor.accel = ao_data_accel(packet); telemetry.mega_sensor.pres = ao_data_pres(packet); telemetry.mega_sensor.temp = ao_data_temp(packet); @@ -269,30 +284,6 @@ ao_send_mini(void) #endif /* AO_SEND_MINI */ -#ifdef AO_SEND_ALL_BARO -static uint8_t ao_baro_sample; - -static void -ao_send_baro(void) -{ - uint8_t sample = ao_sample_data; - uint8_t samples = (sample - ao_baro_sample) & (AO_DATA_RING - 1); - - if (samples > 12) { - ao_baro_sample = (ao_baro_sample + (samples - 12)) & (AO_DATA_RING - 1); - samples = 12; - } - telemetry.generic.tick = ao_data_ring[sample].tick; - telemetry.generic.type = AO_TELEMETRY_BARO; - telemetry.baro.samples = samples; - for (sample = 0; sample < samples; sample++) { - telemetry.baro.baro[sample] = ao_data_ring[ao_baro_sample].adc.pres; - ao_baro_sample = ao_data_ring_next(ao_baro_sample); - } - ao_radio_send(&telemetry, sizeof (telemetry)); -} -#endif - static __pdata int8_t ao_telemetry_config_max; static __pdata int8_t ao_telemetry_config_cur; @@ -332,6 +323,7 @@ ao_send_configuration(void) #if HAS_GPS +static __pdata int8_t ao_telemetry_gps_max; static __pdata int8_t ao_telemetry_loc_cur; static __pdata int8_t ao_telemetry_sat_cur; @@ -348,7 +340,7 @@ ao_send_location(void) telemetry.location.tick = ao_gps_tick; ao_mutex_put(&ao_gps_mutex); ao_radio_send(&telemetry, sizeof (telemetry)); - ao_telemetry_loc_cur = ao_telemetry_config_max; + ao_telemetry_loc_cur = ao_telemetry_gps_max; } } @@ -365,7 +357,7 @@ ao_send_satellite(void) AO_MAX_GPS_TRACKING * sizeof (struct ao_telemetry_satellite_info)); ao_mutex_put(&ao_gps_mutex); ao_radio_send(&telemetry, sizeof (telemetry)); - ao_telemetry_sat_cur = ao_telemetry_config_max; + ao_telemetry_sat_cur = ao_telemetry_gps_max; } } #endif @@ -411,6 +403,7 @@ ao_telemetry(void) while (ao_telemetry_interval == 0) ao_sleep(&telemetry); time = ao_time(); + ao_telemetry_time = time; #if HAS_RDF ao_rdf_time = time; #endif @@ -418,79 +411,85 @@ ao_telemetry(void) ao_aprs_time = time; #endif while (ao_telemetry_interval) { -#if HAS_APRS + time = ao_time() + AO_SEC_TO_TICKS(100); +#ifndef SIMPLIFY if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY)) #endif { -#ifdef AO_SEND_ALL_BARO - ao_send_baro(); +#ifndef SIMPLIFY + if ( (int16_t) (ao_time() - ao_telemetry_time) >= 0) #endif - -#if HAS_FLIGHT + { + ao_telemetry_time = ao_time() + ao_telemetry_interval; # ifdef AO_SEND_MEGA - ao_send_mega_sensor(); - ao_send_mega_data(); + ao_send_mega_sensor(); + ao_send_mega_data(); # endif # ifdef AO_SEND_METRUM - ao_send_metrum_sensor(); - ao_send_metrum_data(); + ao_send_metrum_sensor(); + ao_send_metrum_data(); # endif # ifdef AO_SEND_MINI - ao_send_mini(); + ao_send_mini(); # endif # ifdef AO_TELEMETRY_SENSOR - ao_send_sensor(); + ao_send_sensor(); # endif -#endif /* HAS_FLIGHT */ - #if HAS_COMPANION - if (ao_companion_running) - ao_send_companion(); + if (ao_companion_running) + ao_send_companion(); #endif - ao_send_configuration(); #if HAS_GPS - ao_send_location(); - ao_send_satellite(); + ao_send_location(); + ao_send_satellite(); +#endif + ao_send_configuration(); + } +#ifndef SIMPLIFY + time = ao_telemetry_time; #endif } -#ifndef AO_SEND_ALL_BARO #if HAS_RDF - if (ao_rdf && -#if HAS_APRS - !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) && -#endif /* HAS_APRS */ - (int16_t) (ao_time() - ao_rdf_time) >= 0) + if (ao_rdf +#ifndef SIMPLIFY + && !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) +#endif + ) { + if ((int16_t) (ao_time() - ao_rdf_time) >= 0) { #if HAS_IGNITE_REPORT - uint8_t c; -#endif /* HAS_IGNITE_REPORT */ - ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; + uint8_t c; +#endif + ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; #if HAS_IGNITE_REPORT - if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter())) - ao_radio_continuity(c); - else -#endif /* HAS_IGNITE_REPORT*/ - ao_radio_rdf(); + if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter())) + ao_radio_continuity(c); + else +#endif + ao_radio_rdf(); + } +#ifndef SIMPLIFY + if ((int16_t) (time - ao_rdf_time) > 0) + time = ao_rdf_time; +#endif } #endif /* HAS_RDF */ #if HAS_APRS - if (ao_config.aprs_interval != 0 && - (int16_t) (ao_time() - ao_aprs_time) >= 0) - { - ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval); - ao_aprs_send(); + if (ao_config.aprs_interval != 0) { + if ((int16_t) (ao_time() - ao_aprs_time) >= 0) { + ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval); + ao_aprs_send(); + } + if ((int16_t) (time - ao_aprs_time) > 0) + time = ao_aprs_time; } #endif /* HAS_APRS */ -#endif /* !AO_SEND_ALL_BARO */ - time += ao_telemetry_interval; delay = time - ao_time(); if (delay > 0) { ao_alarm(delay); ao_sleep(&telemetry); ao_clear_alarm(); } - else - time = ao_time(); } } } @@ -547,21 +546,31 @@ ao_telemetry_set_interval(uint16_t interval) ao_telemetry_companion_cur = cur; #endif - ao_telemetry_config_max = AO_SEC_TO_TICKS(5) / interval; -#if HAS_COMPANION - if (ao_telemetry_config_max > cur) - cur++; - ao_telemetry_config_cur = cur; -#endif - #if HAS_GPS - if (ao_telemetry_config_max > cur) + ao_telemetry_gps_max = AO_SEC_TO_TICKS(1) / interval; + if (ao_telemetry_gps_max > cur) cur++; ao_telemetry_loc_cur = cur; - if (ao_telemetry_config_max > cur) + if (ao_telemetry_gps_max > cur) cur++; ao_telemetry_sat_cur = cur; #endif + + ao_telemetry_config_max = AO_SEC_TO_TICKS(5) / interval; + if (ao_telemetry_config_max > cur) + cur++; + ao_telemetry_config_cur = cur; + +#ifndef SIMPLIFY + ao_telemetry_time = +#if HAS_RDF + ao_rdf_time = +#endif +#if HAS_APRS + ao_aprs_time = +#endif + ao_time(); +#endif ao_wakeup(&telemetry); } diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index 83d432cf..711e0d36 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -116,12 +116,16 @@ struct ao_telemetry_location { /* 32 */ }; -#if HAS_GPS - #ifndef HAS_WIDE_GPS #define HAS_WIDE_GPS 1 #endif +#ifdef HAS_TELEMETRY +#ifndef HAS_RDF +#define HAS_RDF 1 +#endif +#endif + #if HAS_WIDE_GPS typedef int32_t gps_alt_t; #define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) @@ -135,8 +139,6 @@ typedef int16_t gps_alt_t; (l)->altitude_low = (a))) #endif /* HAS_WIDE_GPS */ -#endif /* HAS_GPS */ - #define AO_TELEMETRY_SATELLITE 0x06 struct ao_telemetry_satellite_info { diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index 21a7a8e5..69f2cbfb 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -30,8 +30,19 @@ #define ao_gpio_get(port, bit, pin) (lpc_gpio.byte[lpc_all_bit(port,bit)]) +#define PORT0_JTAG_REGS ((1 << 11) | (1 << 12) | (1 << 14)) + +static inline void lpc_set_gpio(int port, int bit) { + if (port == 0 && (1 << bit) & (PORT0_JTAG_REGS)) { + vuint32_t *_ioconf = &lpc_ioconf.pio0_0 + ((port)*24+(bit)); + + *_ioconf = (*_ioconf & ~LPC_IOCONF_FUNC_MASK) | LPC_IOCONF_FUNC_PIO0_11; + } +} + #define ao_enable_output(port,bit,pin,v) do { \ ao_enable_port(port); \ + lpc_set_gpio(port,bit); \ ao_gpio_set(port, bit, pin, v); \ lpc_gpio.dir[port] |= (1 << bit); \ } while (0) @@ -52,6 +63,7 @@ #define ao_enable_input(port,bit,mode) do { \ ao_enable_port(port); \ + lpc_set_gpio(port,bit); \ lpc_gpio.dir[port] &= ~(1 << bit); \ ao_gpio_set_mode(port,bit,mode); \ } while (0) @@ -201,7 +213,7 @@ void ao_spi_put(uint8_t spi_index); void -ao_spi_send(void *block, uint16_t len, uint8_t spi_index); +ao_spi_send(const void *block, uint16_t len, uint8_t spi_index); void ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index); @@ -210,7 +222,7 @@ void ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); void -ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index); +ao_spi_duplex(const void *out, void *in, uint16_t len, uint8_t spi_index); extern uint16_t ao_spi_speed[LPC_NUM_SPI]; diff --git a/src/lpc/ao_led_lpc.c b/src/lpc/ao_led_lpc.c index d983437c..a0b293b9 100644 --- a/src/lpc/ao_led_lpc.c +++ b/src/lpc/ao_led_lpc.c @@ -59,6 +59,15 @@ void ao_led_init(AO_PORT_TYPE enable) { ao_led_enable = enable; - lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO); + ao_enable_port(LED_PORT); + if (LED_PORT == 0) { + if (enable & (1 << 11)) + lpc_ioconf.pio0_11 = LPC_IOCONF_FUNC_PIO0_11 | (1 << LPC_IOCONF_ADMODE); + if (enable & (1 << 12)) + lpc_ioconf.pio0_12 = LPC_IOCONF_FUNC_PIO0_12 | (1 << LPC_IOCONF_ADMODE); + if (enable & (1 << 14)) + lpc_ioconf.pio0_14 = LPC_IOCONF_FUNC_PIO0_14 | (1 << LPC_IOCONF_ADMODE); + } lpc_gpio.dir[LED_PORT] |= enable; + ao_led_off(enable); } diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index e72b8286..bc8f9c69 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -43,9 +43,9 @@ static struct lpc_ssp * const ao_lpc_ssp[LPC_NUM_SPI] = { &lpc_ssp0, &lpc_ssp1 } } while (0) void -ao_spi_send(void *block, uint16_t len, uint8_t id) +ao_spi_send(const void *block, uint16_t len, uint8_t id) { - uint8_t *b = block; + const uint8_t *b = block; struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; spi_loop(len, *b++, (void)); @@ -69,9 +69,9 @@ ao_spi_recv(void *block, uint16_t len, uint8_t id) } void -ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t id) +ao_spi_duplex(const void *out, void *in, uint16_t len, uint8_t id) { - uint8_t *o = out; + const uint8_t *o = out; uint8_t *i = in; struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id]; diff --git a/src/microsplash/.gitignore b/src/microsplash/.gitignore new file mode 100644 index 00000000..5f6fe3b2 --- /dev/null +++ b/src/microsplash/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +microsplash-* diff --git a/src/microsplash/Makefile b/src/microsplash/Makefile new file mode 100644 index 00000000..10cb825b --- /dev/null +++ b/src/microsplash/Makefile @@ -0,0 +1,121 @@ +# +# Tiny AltOS build +# +# +vpath % ../attiny:../drivers:../kernel:../product:.. +vpath ao-make-product.5c ../util +vpath make-altitude-pa ../util + +include ../avr/Makefile.defs + +PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries +PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex + +MCU=attiny85 +DUDECPUTYPE=t85 +#PROGRAMMER=stk500v2 -P usb +LOADSLOW=-i 32 -B 32 +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: + +#LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x + +ALTOS_SRC = \ + ao_micropeak.c \ + ao_spi_attiny.c \ + ao_led.c \ + ao_clock.c \ + ao_ms5607.c \ + ao_exti.c \ + ao_convert_pa.c \ + ao_report_micro.c \ + ao_notask.c \ + ao_eeprom_tiny.c \ + ao_panic.c \ + ao_log_micro.c \ + ao_async.c \ + ao_microflight.c \ + ao_microkalman.c + +INC=\ + ao.h \ + ao_pins.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_exti.h \ + ao_ms5607.h \ + ao_log_micro.h \ + ao_micropeak.h \ + altitude-pa.h + +IDPRODUCT=0 +PRODUCT=MicroSplash-v0.1 +PRODUCT_DEF=-DMICROPEAK +CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY + +NICKLE=nickle + +PROG=microsplash-v1.0 + +SRC=$(ALTOS_SRC) +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) $(PROG).hex + +CHECK=sh ../util/check-avr-mem + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +load-slow: $(PROG).hex + $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.o: ao_product.c ao_product.h + +%.o : %.c $(INC) + $(call quiet,CC) -c $(CFLAGS) $< + +distclean: clean + +clean: + rm -f *.o $(PROG) $(PROG).hex + rm -f ao_product.h + + +publish: $(PROG).hex + cp -a $(PROG).hex $(PUBLISH_FILE) + +load-product: + $(LOADCMD) $(LOADARG)$(PUBLISH_FILE) + +load-product-slow: + $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE) + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +install: + +uninstall: + +$(OBJ): ao_product.h $(INC) diff --git a/src/microsplash/ao_pins.h b/src/microsplash/ao_pins.h new file mode 100644 index 00000000..37885ec2 --- /dev/null +++ b/src/microsplash/ao_pins.h @@ -0,0 +1,70 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ +#include + +#define AO_LED_ORANGE (1<<4) +#define AO_LED_SERIAL 4 +#define AO_LED_PANIC AO_LED_ORANGE +#define AO_LED_REPORT AO_LED_ORANGE +#define LEDS_AVAILABLE (AO_LED_ORANGE) +#define USE_SERIAL_1_STDIN 0 +#define HAS_USB 0 +#define PACKET_HAS_SLAVE 0 +#define HAS_SERIAL_1 0 +#define HAS_TASK 0 +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define HAS_EEPROM 0 +#define HAS_BEEP 0 +#define AVR_CLOCK 250000UL + +/* SPI */ +#define SPI_PORT PORTB +#define SPI_PIN PINB +#define SPI_DIR DDRB +#define AO_MS5607_CS_PORT PORTB +#define AO_MS5607_CS_PIN 3 + +/* MS5607 */ +#define AO_MS5607_SPI_INDEX 0 +#define AO_MS5607_MISO_PORT PORTB +#define AO_MS5607_MISO_PIN 0 +#define AO_MS5607_BARO_OVERSAMPLE 4096 +#define AO_MS5607_TEMP_OVERSAMPLE 1024 + +/* I2C */ +#define I2C_PORT PORTB +#define I2C_PIN PINB +#define I2C_DIR DDRB +#define I2C_PIN_SCL PINB2 +#define I2C_PIN_SDA PINB0 + +#define AO_CONST_ATTRIB PROGMEM +typedef int32_t alt_t; +#define FETCH_ALT(o) ((alt_t) pgm_read_dword(&altitude_table[o])) + +#define AO_ALT_VALUE(x) ((x) * (alt_t) 10) + +/* Pressure change (in Pa) to detect boost */ +#ifndef BOOST_DETECT +#define BOOST_DETECT 120 /* 10m at sea level, 12m at 2000m */ +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/microwater/.gitignore b/src/microwater/.gitignore deleted file mode 100644 index 0573d989..00000000 --- a/src/microwater/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ao_product.h -microwater-* diff --git a/src/microwater/Makefile b/src/microwater/Makefile deleted file mode 100644 index a49cda4b..00000000 --- a/src/microwater/Makefile +++ /dev/null @@ -1,121 +0,0 @@ -# -# Tiny AltOS build -# -# -vpath % ../attiny:../drivers:../kernel:../product:.. -vpath ao-make-product.5c ../util -vpath make-altitude-pa ../util - -include ../avr/Makefile.defs - -PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries -PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex - -MCU=attiny85 -DUDECPUTYPE=t85 -#PROGRAMMER=stk500v2 -P usb -LOADSLOW=-i 32 -B 32 -LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: - -#LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x - -ALTOS_SRC = \ - ao_micropeak.c \ - ao_spi_attiny.c \ - ao_led.c \ - ao_clock.c \ - ao_ms5607.c \ - ao_exti.c \ - ao_convert_pa.c \ - ao_report_micro.c \ - ao_notask.c \ - ao_eeprom_tiny.c \ - ao_panic.c \ - ao_log_micro.c \ - ao_async.c \ - ao_microflight.c \ - ao_microkalman.c - -INC=\ - ao.h \ - ao_pins.h \ - ao_arch.h \ - ao_arch_funcs.h \ - ao_exti.h \ - ao_ms5607.h \ - ao_log_micro.h \ - ao_micropeak.h \ - altitude-pa.h - -IDPRODUCT=0 -PRODUCT=MicroWater-v0.1 -PRODUCT_DEF=-DMICROPEAK -CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product -CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY - -NICKLE=nickle - -PROG=microwater-v0.1 - -SRC=$(ALTOS_SRC) -OBJ=$(SRC:.c=.o) - -V=0 -# The user has explicitly enabled quiet compilation. -ifeq ($(V),0) -quiet = @printf " $1 $2 $@\n"; $($1) -endif -# Otherwise, print the full command line. -quiet ?= $($1) - -all: $(PROG) $(PROG).hex - -CHECK=sh ../util/check-avr-mem - -$(PROG): Makefile $(OBJ) - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) - $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) - -$(PROG).hex: $(PROG) - avr-size $(PROG) - $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ - - -load: $(PROG).hex - $(LOADCMD) $(LOADARG)$(PROG).hex - -load-slow: $(PROG).hex - $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex - -ao_product.h: ao-make-product.5c ../Version - $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ - -ao_product.o: ao_product.c ao_product.h - -%.o : %.c $(INC) - $(call quiet,CC) -c $(CFLAGS) $< - -distclean: clean - -clean: - rm -f *.o $(PROG) $(PROG).hex - rm -f ao_product.h - - -publish: $(PROG).hex - cp -a $(PROG).hex $(PUBLISH_FILE) - -load-product: - $(LOADCMD) $(LOADARG)$(PUBLISH_FILE) - -load-product-slow: - $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE) - -../altitude-pa.h: make-altitude-pa - nickle $< > $@ - -install: - -uninstall: - -$(OBJ): ao_product.h $(INC) diff --git a/src/microwater/ao_pins.h b/src/microwater/ao_pins.h deleted file mode 100644 index 37885ec2..00000000 --- a/src/microwater/ao_pins.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _AO_PINS_H_ -#define _AO_PINS_H_ -#include - -#define AO_LED_ORANGE (1<<4) -#define AO_LED_SERIAL 4 -#define AO_LED_PANIC AO_LED_ORANGE -#define AO_LED_REPORT AO_LED_ORANGE -#define LEDS_AVAILABLE (AO_LED_ORANGE) -#define USE_SERIAL_1_STDIN 0 -#define HAS_USB 0 -#define PACKET_HAS_SLAVE 0 -#define HAS_SERIAL_1 0 -#define HAS_TASK 0 -#define HAS_MS5607 1 -#define HAS_MS5611 0 -#define HAS_EEPROM 0 -#define HAS_BEEP 0 -#define AVR_CLOCK 250000UL - -/* SPI */ -#define SPI_PORT PORTB -#define SPI_PIN PINB -#define SPI_DIR DDRB -#define AO_MS5607_CS_PORT PORTB -#define AO_MS5607_CS_PIN 3 - -/* MS5607 */ -#define AO_MS5607_SPI_INDEX 0 -#define AO_MS5607_MISO_PORT PORTB -#define AO_MS5607_MISO_PIN 0 -#define AO_MS5607_BARO_OVERSAMPLE 4096 -#define AO_MS5607_TEMP_OVERSAMPLE 1024 - -/* I2C */ -#define I2C_PORT PORTB -#define I2C_PIN PINB -#define I2C_DIR DDRB -#define I2C_PIN_SCL PINB2 -#define I2C_PIN_SDA PINB0 - -#define AO_CONST_ATTRIB PROGMEM -typedef int32_t alt_t; -#define FETCH_ALT(o) ((alt_t) pgm_read_dword(&altitude_table[o])) - -#define AO_ALT_VALUE(x) ((x) * (alt_t) 10) - -/* Pressure change (in Pa) to detect boost */ -#ifndef BOOST_DETECT -#define BOOST_DETECT 120 /* 10m at sea level, 12m at 2000m */ -#endif - -#endif /* _AO_PINS_H_ */ diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 7ad3b4b8..42f1a2e5 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -74,7 +74,7 @@ void ao_spi_put(uint8_t spi_index); void -ao_spi_send(void *block, uint16_t len, uint8_t spi_index); +ao_spi_send(const void *block, uint16_t len, uint8_t spi_index); void ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index); diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 885af544..7eaa3924 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -42,7 +42,7 @@ static const struct ao_spi_stm_info ao_spi_stm_info[STM_NUM_SPI] = { static uint8_t spi_dev_null; void -ao_spi_send(void *block, uint16_t len, uint8_t spi_index) +ao_spi_send(const void *block, uint16_t len, uint8_t spi_index) { struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; uint8_t mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; @@ -51,7 +51,7 @@ ao_spi_send(void *block, uint16_t len, uint8_t spi_index) /* Set up the transmit DMA to deliver data */ ao_dma_set_transfer(mosi_dma_index, &stm_spi->dr, - block, + (void *) block, len, (0 << STM_DMA_CCR_MEM2MEM) | (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | diff --git a/src/teledongle-v1.8/.gitignore b/src/teledongle-v1.8/.gitignore new file mode 100644 index 00000000..9a30cbb6 --- /dev/null +++ b/src/teledongle-v1.8/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +teledongle-*.elf diff --git a/src/teledongle-v1.8/Makefile b/src/teledongle-v1.8/Makefile new file mode 100644 index 00000000..6c05ce9f --- /dev/null +++ b/src/teledongle-v1.8/Makefile @@ -0,0 +1,88 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_pins.h \ + ao_product.h \ + ao_task.h \ + ao_whiten.h \ + stm32l.h \ + ao_cc1200.h \ + ao_cc1200_CC1200.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_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cc1200.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_freq.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_send_packet.c \ + ao_eeprom_stm.c \ + ao_monitor.c \ + ao_packet_master.c \ + ao_packet.c + +PRODUCT=TeleDongle-v1.8 +PRODUCT_DEF=-DTELEDONGLE +IDPRODUCT=0x000c + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=teledongle-v1.8 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_teledongle.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +$(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 $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/teledongle-v1.8/ao_pins.h b/src/teledongle-v1.8/ao_pins.h new file mode 100644 index 00000000..cff3e5e8 --- /dev/null +++ b/src/teledongle-v1.8/ao_pins.h @@ -0,0 +1,147 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* Using TeleMetrum v1.9 board */ + +#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 0 + +#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 0 +#define SERIAL_3_PD8_PD9 0 + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 1 +#define USE_STORAGE_CONFIG 0 +#define USE_EEPROM_CONFIG 1 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_RADIO 1 +#define HAS_TELEMETRY 0 +#define HAS_RSSI 0 + +#define HAS_SPI_1 0 +#define SPI_1_PA5_PA6_PA7 0 /* Barometer */ +#define SPI_1_PB3_PB4_PB5 0 +#define SPI_1_PE13_PE14_PE15 0 /* Accelerometer */ + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 1 /* Radio */ +#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 PACKET_HAS_SLAVE 0 +#define PACKET_HAS_MASTER 1 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_0_ENABLE STM_RCC_AHBENR_GPIOCEN +#define LED_PORT_0 (&stm_gpioc) +#define LED_PORT_0_MASK (0xffff) +#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 0 +#define HAS_LOG 0 + +/* + * Telemetry monitoring + */ +#define HAS_MONITOR 1 +#define LEGACY_MONITOR 0 +#define HAS_MONITOR_PUT 1 +#define AO_MONITOR_LED AO_LED_GREEN +#define AO_MONITOR_BAD AO_LED_RED + +/* + * Radio (cc1200) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 5695733 + +#define AO_FEC_DEBUG 0 +#define AO_CC1200_SPI_CS_PORT (&stm_gpioc) +#define AO_CC1200_SPI_CS_PIN 5 +#define AO_CC1200_SPI_BUS AO_SPI_2_PB13_PB14_PB15 +#define AO_CC1200_SPI stm_spi2 + +#define AO_CC1200_INT_PORT (&stm_gpioe) +#define AO_CC1200_INT_PIN 1 + +#define AO_CC1200_INT_GPIO 2 +#define AO_CC1200_INT_GPIO_IOCFG CC1200_IOCFG2 + +/* + * Profiling Viterbi decoding + */ + +#ifndef AO_PROFILE +#define AO_PROFILE 0 +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/teledongle-v1.8/ao_teledongle.c b/src/teledongle-v1.8/ao_teledongle.c new file mode 100644 index 00000000..5ce6b15b --- /dev/null +++ b/src/teledongle-v1.8/ao_teledongle.c @@ -0,0 +1,54 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include + +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_RED); + ao_timer_init(); + + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_cmd_init(); + + ao_usb_init(); + ao_radio_init(); + ao_monitor_init(); + ao_packet_master_init(); + ao_send_packet_init(); + + ao_config_init(); + + ao_led_off(AO_LED_RED); + ao_start_scheduler(); + return 0; +} diff --git a/src/teledongle-v1.9/Makefile b/src/teledongle-v1.9/Makefile index a8999c27..78deb9e2 100644 --- a/src/teledongle-v1.9/Makefile +++ b/src/teledongle-v1.9/Makefile @@ -3,7 +3,7 @@ # # -include ../stm/Makefile.defs +include ../lpc/Makefile.defs INC = \ ao.h \ @@ -14,26 +14,11 @@ INC = \ ao_product.h \ ao_task.h \ ao_whiten.h \ - stm32l.h \ + lpc.h \ + ao_cc1200.h \ + ao_cc1200_CC1200.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 - -# ao_monitor.c \ -# ao_rssi.c \ -# ao_send_packet.c \ -# ao_packet_master.c \ -# ao_packet.c - - ALTOS_SRC = \ ao_boot_chain.c \ ao_interrupt.c \ @@ -43,23 +28,25 @@ ALTOS_SRC = \ ao_cmd.c \ ao_config.c \ ao_task.c \ - ao_led.c \ + ao_led_lpc.c \ ao_stdio.c \ ao_panic.c \ - ao_timer.c \ + ao_timer_lpc.c \ ao_mutex.c \ ao_freq.c \ - ao_dma_stm.c \ - ao_spi_stm.c \ - ao_usb_stm.c \ - ao_exti_stm.c \ - ao_eeprom_stm.c + ao_spi_lpc.c \ + ao_usb_lpc.c \ + ao_exti_lpc.c \ + ao_send_packet.c \ + ao_monitor.c \ + ao_packet_master.c \ + ao_packet.c PRODUCT=TeleDongle-v1.9 PRODUCT_DEF=-DTELEDONGLE IDPRODUCT=0x000c -CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -Os -g PROGNAME=teledongle-v1.9 PROG=$(PROGNAME)-$(VERSION).elf @@ -78,6 +65,9 @@ $(OBJ): $(INC) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ +load: $(PROG) + lpc-load $(PROG) + distclean: clean clean: diff --git a/src/teledongle-v1.9/ao_pins.h b/src/teledongle-v1.9/ao_pins.h index bbc42a5d..f8889c4a 100644 --- a/src/teledongle-v1.9/ao_pins.h +++ b/src/teledongle-v1.9/ao_pins.h @@ -20,83 +20,49 @@ #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 +#define AO_STACK_SIZE 324 -/* Run APB1 at 16MHz (HCLK/2) */ -#define AO_APB1_PRESCALER 2 -#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 +#define HAS_TASK_QUEUE 1 -/* Run APB2 at 16MHz (HCLK/2) */ -#define AO_APB2_PRESCALER 2 -#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 +#define IS_FLASH_LOADER 0 -#define HAS_SERIAL_1 0 -#define USE_SERIAL_1_STDIN 0 -#define SERIAL_1_PB6_PB7 0 -#define SERIAL_1_PA9_PA10 0 +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 -#define HAS_SERIAL_2 0 -#define USE_SERIAL_2_STDIN 0 -#define SERIAL_2_PA2_PA3 0 -#define SERIAL_2_PD5_PD6 0 +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 -#define HAS_SERIAL_3 0 -#define USE_SERIAL_3_STDIN 0 -#define SERIAL_3_PB10_PB11 0 -#define SERIAL_3_PC10_PC11 0 -#define SERIAL_3_PD8_PD9 0 +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 -#define HAS_EEPROM 1 -#define USE_INTERNAL_FLASH 1 +#define HAS_EEPROM 0 +#define USE_INTERNAL_FLASH 0 #define USE_STORAGE_CONFIG 0 -#define USE_EEPROM_CONFIG 1 +#define USE_EEPROM_CONFIG 0 + #define HAS_USB 1 +#define HAS_USB_CONNECT 0 +#define HAS_USB_VBUS 0 +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + #define HAS_BEEP 0 #define HAS_RADIO 1 #define HAS_TELEMETRY 0 -#define HAS_RSSI 1 - -#define HAS_SPI_1 0 -#define SPI_1_PA5_PA6_PA7 0 /* Barometer */ -#define SPI_1_PB3_PB4_PB5 0 -#define SPI_1_PE13_PE14_PE15 0 /* Accelerometer */ - -#define HAS_SPI_2 1 -#define SPI_2_PB13_PB14_PB15 1 /* Radio */ -#define SPI_2_PD1_PD3_PD4 0 -#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz +#define HAS_RSSI 0 -#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 HAS_SPI_0 1 +#define SPI_SCK0_P0_6 1 #define PACKET_HAS_SLAVE 0 #define PACKET_HAS_MASTER 1 #define LOW_LEVEL_DEBUG 0 -#define LED_PORT_0_ENABLE STM_RCC_AHBENR_GPIOCEN -#define LED_PORT_0 (&stm_gpioc) -#define LED_PORT_0_MASK (0xffff) -#define LED_PORT_0_SHIFT 0 -#define LED_PIN_RED 8 -#define LED_PIN_GREEN 9 +#define LED_PORT 0 +#define LED_PIN_RED 14 +#define LED_PIN_GREEN 7 #define AO_LED_RED (1 << LED_PIN_RED) #define AO_LED_GREEN (1 << LED_PIN_GREEN) @@ -110,10 +76,11 @@ /* * Telemetry monitoring */ -#define HAS_MONITOR 0 +#define HAS_MONITOR 1 #define LEGACY_MONITOR 0 #define HAS_MONITOR_PUT 1 #define AO_MONITOR_LED AO_LED_GREEN +#define AO_MONITOR_BAD AO_LED_RED /* * Radio (cc1200) @@ -121,16 +88,16 @@ /* gets pretty close to 434.550 */ -#define AO_RADIO_CAL_DEFAULT 0x6ca333 +#define AO_RADIO_CAL_DEFAULT 5695733 #define AO_FEC_DEBUG 0 -#define AO_CC1200_SPI_CS_PORT (&stm_gpioc) -#define AO_CC1200_SPI_CS_PIN 5 -#define AO_CC1200_SPI_BUS AO_SPI_2_PB13_PB14_PB15 -#define AO_CC1200_SPI stm_spi2 +#define AO_CC1200_SPI_CS_PORT 0 +#define AO_CC1200_SPI_CS_PIN 3 +#define AO_CC1200_SPI_BUS 0 +#define AO_CC1200_SPI 0 -#define AO_CC1200_INT_PORT (&stm_gpioe) -#define AO_CC1200_INT_PIN 1 +#define AO_CC1200_INT_PORT 0 +#define AO_CC1200_INT_PIN 2 #define AO_CC1200_INT_GPIO 2 #define AO_CC1200_INT_GPIO_IOCFG CC1200_IOCFG2 diff --git a/src/teledongle-v1.9/ao_teledongle.c b/src/teledongle-v1.9/ao_teledongle.c index ac1e3c9f..02b93efe 100644 --- a/src/teledongle-v1.9/ao_teledongle.c +++ b/src/teledongle-v1.9/ao_teledongle.c @@ -35,20 +35,19 @@ main(void) ao_timer_init(); ao_spi_init(); - ao_dma_init(); ao_exti_init(); ao_cmd_init(); ao_usb_init(); ao_radio_init(); -// ao_monitor_init(); -// ao_rssi_init(AO_LED_RED); -// ao_packet_master_init(); -// ao_send_packet_init(); + ao_monitor_init(); + ao_packet_master_init(); + ao_send_packet_init(); ao_config_init(); + ao_led_off(AO_LED_RED); ao_start_scheduler(); return 0; } diff --git a/src/teledongle-v1.9/flash-loader/Makefile b/src/teledongle-v1.9/flash-loader/Makefile index 70ddaad4..a5642b46 100644 --- a/src/teledongle-v1.9/flash-loader/Makefile +++ b/src/teledongle-v1.9/flash-loader/Makefile @@ -4,4 +4,4 @@ TOPDIR=../.. HARDWARE=teledongle-v1.9 -include $(TOPDIR)/stm/Makefile-flash.defs +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/teledongle-v1.9/flash-loader/ao_pins.h b/src/teledongle-v1.9/flash-loader/ao_pins.h index 1af92f13..aee5be27 100644 --- a/src/teledongle-v1.9/flash-loader/ao_pins.h +++ b/src/teledongle-v1.9/flash-loader/ao_pins.h @@ -18,17 +18,18 @@ #ifndef _AO_PINS_H_ #define _AO_PINS_H_ -/* External crystal at 8MHz */ -#define AO_HSE 8000000 +#include -#include +/* Debug port TXD (pin 6) */ -/* Companion port cs_companion0 PD0 */ - -#define AO_BOOT_PIN 1 -#define AO_BOOT_APPLICATION_GPIO stm_gpiod -#define AO_BOOT_APPLICATION_PIN 0 +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 19 #define AO_BOOT_APPLICATION_VALUE 1 #define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 20 + #endif /* _AO_PINS_H_ */ diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 5ea205d6..83efbb4f 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -59,6 +59,7 @@ struct ao_telemetry_location { typedef int32_t gps_alt_t; #define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_GPS_ORIG_ALTITUDE(l) AO_TELEMETRY_LOCATION_ALTITUDE(l) #define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->altitude_high = (a) >> 16), \ ((l)->altitude_low = (a)))