-SUBDIRS=ao-tools src doc icon altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid telegps
+SUBDIRS=ao-tools src doc icon altoslib libaltos altosuilib altosui micropeak ao-utils altosdroid telegps map-server
EXTRA_DIST = ChangeLog
- update the version and date in configure.ac if Bdale hasn't already
+ - follow instructions in doc/RELNOTES
+
- make sure there is a doc/release-notes-<version>.inc
- make sure doc/release-notes.inc points at that
- make sure build environment is up to date
sudo cowbuilder --update
+ - ensure i386 build support is available, and we have tools to build
+ installers for Windows and Mac OS X
+
+ sudo dpkg --add-architecture i386
+ sudo apt update
+ sudo apt install gcc-multilib genisoimage nsis
+ (need some mingw packages too, but not sure which offhand)
+
- make sure ~/web/altusmetrum has no pending pullable commits
git checkout master
- at this point we have packages in ~/debian/build-area/altos, now
we move on to the non-Debian part of the release process
- make distclean
+ make distclean (just to be sure, this should do nothing)
./autogen.sh --enable-multi-arch \
--with-fat-dir=/home/bdale/web/altusmetrum/
- store a stable copy of ARM binaries for production use
- cp src/chaoskey-v1.0/{*.elf,*.ihx} \
+ cp src/chaoskey-v1.0/{*.elf,*.ihx,*.bin} \
src/easymega-v1.0/{*.elf,*.ihx} \
src/easymini-v1.0/{*.elf,*.ihx} \
src/easymini-v2.0/{*.elf,*.ihx} \
src/telemega-v3.0/{*.elf,*.ihx} \
src/telemetrum-v2.0/{*.elf,*.ihx} \
src/telemini-v3.0/{*.elf,*.ihx} \
+ src/telelco-v2.0/{*.elf,*.ihx} \
+ src/telefireeight-v1.0/{*.elf,*.ihx} \
~/altusmetrumllc/Binaries/
cp src/chaoskey-v1.0/flash-loader/{*.elf,*.bin} \
src/easymega-v1.0/flash-loader/*.elf \
src/telemega-v3.0/flash-loader/*.elf \
src/telemetrum-v2.0/flash-loader/*.elf \
src/telemini-v3.0/flash-loader/{*.elf,*.bin} \
+ src/telelco-v2.0/flash-loader/*.elf \
+ src/telefireeight-v1.0/flash-loader/*.elf \
~/altusmetrumllc/Binaries/loaders/
(cd ~/altusmetrumllc ; git add Binaries ; git commit -a)
- remove previous versions (only keep latest release)
android:layout_height="wrap_content"
android:text="@string/preload_types"
/>
+<!--
<CheckBox android:id="@+id/preload_hybrid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_height="wrap_content"
android:text="@string/preload_terrain"
/>
+-->
<TextView android:id="@+id/preload_min_zoom_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
import android.os.Handler;
//import android.os.Message;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosBluetooth extends AltosDroidLink {
import java.io.*;
import java.lang.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.app.Activity;
import android.graphics.*;
import android.graphics.*;
import android.graphics.drawable.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class SavedState {
long received_time;
// Display the Version
mVersion = (TextView) findViewById(R.id.version);
mVersion.setText("Version: " + BuildInfo.version +
- (AltosVersion.has_google_maps_api_key() ? " maps" : "") +
" Built: " + BuildInfo.builddate + " " + BuildInfo.buildtime + " " + BuildInfo.buildtz +
" (" + BuildInfo.branch + "-" + BuildInfo.commitnum + "-" + BuildInfo.commithash + ")");
import android.os.Handler;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public abstract class AltosDroidLink extends AltosLink {
import java.util.*;
import java.io.*;
import android.location.Location;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public interface AltosDroidMapInterface {
public void onCreateView(AltosDroid altos_droid);
import java.text.*;
import android.content.Context;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosDroidPreferences extends AltosPreferences {
import android.os.Environment;
import android.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
public final static String NAME = "org.altusmetrum.AltosDroid";
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.location.Location;
import android.app.Activity;
import android.graphics.Color;
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.app.Activity;
import android.graphics.*;
AltosMap map;
AltosDroid altos_droid;
- static int scale = 2;
+ static int scale = 1;
AltosLatLon here;
AltosLatLon there;
message = "Internal error";
break;
case AltosMapTile.failed:
- message = "Network error, check connection";
+ message = "Network error";
break;
case AltosMapTile.forbidden:
- message = "Too many requests, try later";
- AltosDebug.debug("Forbidden map response %d\n", AltosMapStore.forbidden_response);
+ message = "Outside of known launch areas";
break;
}
if (message != null) {
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
import android.app.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUsb extends AltosDroidLink {
import android.speech.tts.TextToSpeech.OnInitListener;
import android.location.Location;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosVoice {
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class IdleModeActivity extends Activity {
private EditText callsign;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class IgniterItem {
public String name;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class FrequencyItem {
public AltosFrequency frequency;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class MapTypeActivity extends Activity {
private Button hybrid;
import android.location.LocationListener;
import android.location.Criteria;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
/**
* This Activity appears as a dialog. It lists any paired devices and
private ArrayAdapter<AltosLaunchSite> known_sites_adapter;
+/*
private CheckBox hybrid;
private CheckBox satellite;
private CheckBox roadmap;
private CheckBox terrain;
+*/
private Spinner known_sites_spinner;
private Spinner min_zoom;
return r;
}
+/*
private int bit(CheckBox box, int value) {
if (box.isChecked())
return 1 << value;
return 0;
}
+*/
private int types() {
+/*
return (bit(hybrid, AltosMap.maptype_hybrid) |
bit(satellite, AltosMap.maptype_satellite) |
bit(roadmap, AltosMap.maptype_roadmap) |
bit(terrain, AltosMap.maptype_terrain));
+*/
+ return 1 << AltosMap.maptype_hybrid;
}
private void load() {
latitude = (EditText) findViewById(R.id.preload_latitude);
longitude = (EditText) findViewById(R.id.preload_longitude);
+/*
hybrid = (CheckBox) findViewById(R.id.preload_hybrid);
satellite = (CheckBox) findViewById(R.id.preload_satellite);
roadmap = (CheckBox) findViewById(R.id.preload_roadmap);
terrain = (CheckBox) findViewById(R.id.preload_terrain);
hybrid.setChecked(true);
+*/
min_zoom = (Spinner) findViewById(R.id.preload_min_zoom);
add_numbers(min_zoom,
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class SetupActivity extends Activity {
private Spinner select_rate;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.app.Activity;
import android.os.Bundle;
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.app.Activity;
import android.graphics.*;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.app.Activity;
import android.os.Bundle;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.app.Activity;
import android.os.Bundle;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import java.util.concurrent.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class TelemetryReader extends Thread {
import android.widget.Toast;
import android.location.Criteria;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class TelemetryService extends Service implements AltosIdleMonitorListener {
package org.altusmetrum.AltosDroid;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import android.location.Location;
public class TelemetryState {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.concurrent.*;
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosCRCException extends Exception {
public int rssi;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
}
void write_advanced_header() {
- out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z,tilt");
+ out.printf("accel_x,accel_y,accel_z,gyro_roll,gyro_pitch,gyro_yaw,mag_x,mag_y,mag_z,tilt");
}
double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); }
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
/*
* Calibration and other data needed to construct 'real' values from various data
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosConfigDataException extends Exception {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosConfigValues {
/* set and get all of the dialog values */
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public abstract class AltosDataListener {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosDataProvider {
public void provide_data(AltosDataListener listener) throws InterruptedException, AltosUnknownProduct;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosDistance extends AltosUnits {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosEepromRecordFull extends AltosEepromRecord {
public static final int record_length = 8;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosEepromRecordMega extends AltosEepromRecord {
public static final int record_length = 32;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosEepromRecordMetrum extends AltosEepromRecord {
public static final int record_length = 16;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosEepromRecordMini extends AltosEepromRecord {
public static final int record_length = 16;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosEepromRecordTiny extends AltosEepromRecord implements AltosDataProvider {
public static final int record_length = 2;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.File;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosFilterListener {
void filter_changed(double speed_filter, double accel_filter);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
int flash_addr = (int) image.address;
int image_start = 0;
- action("start", 0);
+ action(AltosFlashListener.flash_start, 0);
action(0, image.data.length);
while (remain > 0 && !aborted) {
int this_time = remain;
action(image.data.length - remain, image.data.length);
}
if (!aborted) {
- action("done", 100);
+ action(AltosFlashListener.flash_done, 100);
if (debug != null) {
debug.set_pc((int) image.address);
debug.resume();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosFlashListener {
+
+ public final static String flash_start = "start";
+ public final static String flash_done = "done";
+
public void position(String label, int percent);
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener {
void reset();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
import java.io.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosFontListener {
void font_size_changed(int font_size);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosForce extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosGPSTimeValue {
public double time;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.lang.Math;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosHeight extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.LinkedList;
int product_len = get_u8(a);
- System.out.printf("Product is at %x length %d\n", a, product_len);
-
- for (int i = 0; i < product_len; i++)
- System.out.printf(" %2d: %02x\n", i, get_u8(a+i));
-
if (product_len <= 0)
return null;
for (int i = 0; i < product_len - 2; i += 2) {
int c = get_u16(a + 2 + i);
- System.out.printf("character %x\n", c);
-
product += Character.toString((char) c);
}
- System.out.printf("product %s\n", product);
+ if (AltosLink.debug)
+ System.out.printf("product %s\n", product);
return product;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosHexsym {
String name;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosIdleMonitorListener {
public void update(AltosState state, AltosListenerState listener_state);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
result.append("\t");
return result;
}
- static NumberFormat get_nf_json() {
- DecimalFormat nf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
- nf.setParseIntegerOnly(false);
- nf.setGroupingUsed(false);
- nf.setMaximumFractionDigits(17);
- nf.setMinimumFractionDigits(0);
- nf.setMinimumIntegerDigits(1);
- nf.setDecimalSeparatorAlwaysShown(false);
- return nf;
- }
- static NumberFormat nf_json = get_nf_json();
+ NumberFormat _nf_json;
+
+ NumberFormat nf_json() {
+ if (_nf_json == null) {
+ DecimalFormat nf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
+ nf.setParseIntegerOnly(false);
+ nf.setGroupingUsed(false);
+ nf.setMaximumFractionDigits(17);
+ nf.setMinimumFractionDigits(0);
+ nf.setMinimumIntegerDigits(1);
+ nf.setDecimalSeparatorAlwaysShown(false);
+ _nf_json = nf;
+ }
+ return _nf_json;
+ }
}
class JsonHash extends JsonUtil {
String dstr = dbuf.toString();
double dval;
try {
- dval = nf_json.parse(dstr).doubleValue();
+ dval = nf_json().parse(dstr).doubleValue();
} catch (ParseException pe) {
return new JsonToken(JsonToken._error, dstr);
}
} else if (Double.isNaN(d_number)) {
result.append("NaN");
} else {
- String dval = nf_json.format(d_number);
+ String dval = nf_json().format(d_number);
if (dval.equals("-0"))
dval = "0";
result.append(dval);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosLatLon {
public double lat;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosLatitude extends AltosLocation {
public String pos() { return "N"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.*;
* 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_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.*;
LinkedList<AltosLaunchSite> sites;
AltosLaunchSiteListener listener;
+ public static String launch_sites_url;
+
void notify_complete() {
listener.notify_launch_sites(sites);
}
try {
String path;
- path = System.getenv(AltosLib.launch_sites_env);
- if (path == null)
- path = AltosLib.launch_sites_url;
+ if (launch_sites_url != null)
+ path = launch_sites_url;
+ else {
+ path = System.getenv(AltosLib.launch_sites_env);
+ if (path == null)
+ path = AltosLib.launch_sites_url;
+ }
url = new URL(path);
URLConnection uc = url.openConnection();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.io.*;
return device_type == product_telemega || device_type == product_easymega;
}
+ public static boolean has_radio(int device_type) {
+ return device_type != product_easymini && device_type != product_easymega;
+ }
+
public static boolean has_gps(int device_type) {
return device_type == product_telemetrum ||
device_type == product_telemega ||
"Compressed", "Uncompressed"
};
- public static final String launch_sites_url = "http://www.altusmetrum.org/AltOS/launch-sites.txt";
+ public static final String launch_sites_url = "https://maps.altusmetrum.org/launch-sites.txt";
public static final String launch_sites_env = "LAUNCH_SITES";
// public static final String launch_sites_url = "file:///home/keithp/misc/text/altusmetrum/AltOS/launch-sites.txt";
+ public static final String unit_info_url = "https://altusmetrum.org/cgi-bin/unitinfo.cgi?sn=%d";
+ public static final String unit_info_env = "UNIT_INFO";
+
public static final int ao_telemetry_standard_len = 32;
public static final int ao_telemetry_0_9_len = 95;
public static final int ao_telemetry_0_8_len = 94;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosLine {
public String line;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public abstract class AltosLocation extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosLongitude extends AltosLocation {
public String pos() { return "E"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.*;
}
public boolean set_maptype(int maptype) {
+/*
if (maptype != this.maptype) {
this.maptype = maptype;
tiles.clear();
repaint();
return true;
}
+*/
return false;
}
AltosLatLon ul = transform.lat_lon(point);
AltosLatLon center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
AltosMapTile tile = map_interface.new_tile(cache, ul, center, zoom, maptype, px_size, scale);
- debug("show state %s url %s\n", AltosMapTile.status_name(tile.store.status()), tile.store.url);
+ int status = tile.store.status();
+ if (status == AltosMapTile.fetching)
+ debug("Fetching %.6f %.6f %d\n", center.lat, center.lon, zoom);
tile.add_listener(this);
tiles.put(point, tile);
}
public void set_load_params(int new_zoom, int new_type, double lat, double lon, int radius, AltosMapTileListener listener) {
if (AltosMap.min_zoom <= new_zoom && new_zoom <= AltosMap.max_zoom)
zoom = new_zoom;
- maptype = new_type;
+/* maptype = new_type; */
load_centre = new AltosLatLon(lat, lon);
load_radius = radius;
load_listener = listener;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosMapCacheListener {
public void map_cache_changed(int map_cache);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
this.min_z = min_z;
this.max_z = max_z;
this.radius = radius;
+/*
this.all_types = all_types;
+*/
+ this.all_types = 1 << AltosMap.maptype_hybrid;
this.scale = scale;
this.abort = false;
start();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosMapLoaderListener {
public abstract void loader_start(int max);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosMapRectangle {
AltosLatLon ul, lr;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.net.*;
chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string));
}
+ public static String google_maps_api_key = null;
+
+ private static String google_map_url(AltosLatLon center, int zoom, int maptype, int px_size, int scale, String format_string) {
+ return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
+ center.lat, center.lon, zoom, px_size, px_size, scale,
+ AltosMap.maptype_names[maptype], format_string, google_maps_api_key);
+ }
+
+ private static String altos_map_url(AltosLatLon center, int zoom, int maptype, int px_size, int scale, String format_string) {
+ return String.format("https://maps.altusmetrum.org/cgi-bin/altos-map?lat=%.6f&lon=%.6f&zoom=%d",
+ center.lat, center.lon, zoom);
+ }
+
private static String map_url(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
String format_string;
- int z = zoom;
if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
format_string = "jpg";
format_string = "png32";
for (int s = 1; s < scale; s <<= 1)
- z--;
+ zoom--;
+
+ px_size /= scale;
- if (AltosVersion.has_google_maps_api_key())
- return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
- center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key);
+ if (google_maps_api_key != null)
+ return google_map_url(center, zoom, maptype, px_size, scale, format_string);
else
- return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s",
- center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string);
+ return altos_map_url(center, zoom, maptype, px_size, scale, format_string);
}
- public int status() {
+ public synchronized int status() {
return status;
}
listener.notify_store(this, status);
}
- static Object forbidden_lock = new Object();
- static long forbidden_time;
- static boolean forbidden_set;
- public static int forbidden_response;
-
private int fetch_url() {
URL u;
return AltosMapTile.bad_request;
}
- byte[] data;
+ byte[] data = null;
URLConnection uc = null;
- try {
- uc = u.openConnection();
- String type = uc.getContentType();
- int contentLength = uc.getContentLength();
- if (uc instanceof HttpURLConnection) {
- int response = ((HttpURLConnection) uc).getResponseCode();
- switch (response) {
- case HttpURLConnection.HTTP_FORBIDDEN:
- case HttpURLConnection.HTTP_PAYMENT_REQUIRED:
- case HttpURLConnection.HTTP_UNAUTHORIZED:
- synchronized (forbidden_lock) {
- forbidden_time = System.nanoTime();
- forbidden_set = true;
- forbidden_response = response;
+
+ int status = AltosMapTile.failed;
+ int tries = 0;
+
+ while (tries < 10 && status != AltosMapTile.fetched) {
+ try {
+ uc = u.openConnection();
+ String type = uc.getContentType();
+ int contentLength = uc.getContentLength();
+ if (uc instanceof HttpURLConnection) {
+ int response = ((HttpURLConnection) uc).getResponseCode();
+ switch (response) {
+ case HttpURLConnection.HTTP_FORBIDDEN:
+ case HttpURLConnection.HTTP_PAYMENT_REQUIRED:
+ case HttpURLConnection.HTTP_UNAUTHORIZED:
return AltosMapTile.forbidden;
}
}
- }
- InputStream in = new BufferedInputStream(uc.getInputStream());
- int bytesRead = 0;
- int offset = 0;
- data = new byte[contentLength];
- while (offset < contentLength) {
- bytesRead = in.read(data, offset, data.length - offset);
- if (bytesRead == -1)
- break;
- offset += bytesRead;
- }
- in.close();
+ InputStream in = new BufferedInputStream(uc.getInputStream());
+ int bytesRead = 0;
+ int offset = 0;
+ data = new byte[contentLength];
+ while (offset < contentLength) {
+ bytesRead = in.read(data, offset, data.length - offset);
+ if (bytesRead == -1)
+ break;
+ offset += bytesRead;
+ }
+ in.close();
- if (offset != contentLength)
- return AltosMapTile.failed;
+ if (offset == contentLength)
+ status = AltosMapTile.fetched;
+ else
+ status = AltosMapTile.failed;
- } catch (IOException e) {
- return AltosMapTile.failed;
+ } catch (IOException e) {
+ status = AltosMapTile.failed;
+ }
+
+ if (status != AltosMapTile.fetched) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ie) {
+ }
+ tries++;
+ System.out.printf("Fetch failed, retrying %d\n", tries);
+ }
}
+ if (status != AltosMapTile.fetched)
+ return status;
+
try {
FileOutputStream out = new FileOutputStream(file);
- out.write(data);
+ if (data != null)
+ out.write(data);
out.flush();
out.close();
} catch (FileNotFoundException e) {
static Object fetch_lock = new Object();
- static final long forbidden_interval = 60l * 1000l * 1000l * 1000l;
- static final long google_maps_ratelimit_ms = 1200;
-
static Object fetcher_lock = new Object();
static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>();
static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>();
- static final int concurrent_fetchers = 128;
+ static int concurrent_fetchers() {
+ if (google_maps_api_key == null)
+ return 16;
+ return 128;
+ }
static void start_fetchers() {
- while (!waiting.isEmpty() && running.size() < concurrent_fetchers) {
+ while (!waiting.isEmpty() && running.size() < concurrent_fetchers()) {
AltosMapStore s = waiting.remove();
running.add(s);
Thread lt = s.make_fetcher_thread();
return;
}
- synchronized(forbidden_lock) {
- if (forbidden_set && (System.nanoTime() - forbidden_time) < forbidden_interval) {
- notify_listeners(AltosMapTile.forbidden);
- return;
- }
- }
-
int new_status;
- if (!AltosVersion.has_google_maps_api_key()) {
- synchronized (fetch_lock) {
- long startTime = System.nanoTime();
- new_status = fetch_url();
- if (new_status == AltosMapTile.fetched) {
- long duration_ms = (System.nanoTime() - startTime) / 1000000;
- if (duration_ms < google_maps_ratelimit_ms) {
- try {
- Thread.sleep(google_maps_ratelimit_ms - duration_ms);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
- } else {
- new_status = fetch_url();
- }
+ new_status = fetch_url();
+
notify_listeners(new_status);
} finally {
finish_fetcher();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosMapStoreListener {
abstract void notify_store(AltosMapStore store, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosMapTileListener {
abstract public void notify_tile(AltosMapTile tile, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosMapTypeListener {
public void map_type_changed(int map_type);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosMapZoomListener {
abstract public void zoom_changed(int zoom);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosNoSymbol extends Exception {
public AltosNoSymbol(String name) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosOrient extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosPointDouble {
public double x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosPointInt {
public int x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosPresTemp {
double pres = AltosLib.MISSING;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosPressure extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.text.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosPyroName extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosQuaternion {
double r; /* real bit */
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosRectangle {
public int x, y, width, height;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
+import java.util.concurrent.*;
-public class AltosRomconfig {
+public class AltosRomconfig implements AltosUnitInfoListener {
public boolean valid;
+ public boolean radio_calibration_broken;
public int version;
public int check;
public int serial_number;
static private long find_address(AltosHexfile hexfile, String name, int len) throws AltosNoSymbol {
AltosHexsym symbol = hexfile.lookup_symbol(name);
if (symbol == null) {
- System.out.printf("no symbol %s\n", name);
throw new AltosNoSymbol(name);
}
if (hexfile.address <= symbol.address && symbol.address + len <= hexfile.max_address) {
- System.out.printf("%s: %x\n", name, symbol.address);
return symbol.address;
}
- System.out.printf("invalid symbol addr %x len %d range is %x - %x\n",
- symbol.address, len, hexfile.address, hexfile.max_address);
throw new AltosNoSymbol(name);
}
final static String ao_radio_cal = "ao_radio_cal";
final static String ao_usb_descriptors = "ao_usb_descriptors";
+ Semaphore unit_info_done;
+
+ public void notify_unit_info(AltosUnitInfo unit_info) {
+ unit_info_done.release();
+ }
+
+ private void fetch_radio_cal() {
+ unit_info_done = new Semaphore(0);
+ AltosUnitInfo info = new AltosUnitInfo(serial_number, this);
+
+ /* Block waiting for the rf calibration data */
+ radio_calibration_broken = true;
+ try {
+ unit_info_done.acquire();
+ int new_cal = info.rfcal();
+ if (new_cal != AltosLib.MISSING) {
+ radio_calibration = new_cal;
+ radio_calibration_broken = false;
+ }
+ } catch (InterruptedException ie) {
+ }
+ }
+
public AltosRomconfig(AltosHexfile hexfile) {
try {
- System.out.printf("Attempting symbols\n");
version = get_int(hexfile, ao_romconfig_version, 2);
- System.out.printf("version %d\n", version);
check = get_int(hexfile, ao_romconfig_check, 2);
- System.out.printf("check %d\n", check);
if (check == (~version & 0xffff)) {
switch (version) {
case 2:
case 1:
serial_number = get_int(hexfile, ao_serial_number, 2);
- System.out.printf("serial %d\n", serial_number);
try {
radio_calibration = get_int(hexfile, ao_radio_cal, 4);
} catch (AltosNoSymbol missing) {
radio_calibration = 0;
}
+
valid = true;
+
+ /* XXX TeleBT v4.0 units originally shipped without RF calibration programmed. Go fetch
+ * the correct value from the web site
+ */
+ if (serial_number == 2584 ||
+ (3686 <= serial_number && serial_number <= 3938 && radio_calibration == 5695485))
+ {
+ fetch_radio_cal();
+ }
+
break;
}
}
- System.out.printf("attempting usbid\n");
usb_id = hexfile.find_usb_id();
- if (usb_id == null)
- System.out.printf("No usb id\n");
- else
- System.out.printf("usb id: %04x:%04x\n",
- usb_id.vid, usb_id.pid);
usb_product = hexfile.find_usb_product();
- if (usb_product == null)
- System.out.printf("No usb product\n");
- else
- System.out.printf("usb product: %s\n", usb_product);
} catch (AltosNoSymbol missing) {
valid = false;
if (addr < base)
base = addr;
- System.out.printf("symbol %s at %x base %x\n", name, addr, base);
} catch (AltosNoSymbol ns) {
if (name_required(name))
throw (ns);
long addr = find_address(hexfile, name, len) + len;
if (addr > bounds)
bounds = addr;
- System.out.printf("symbol %s at %x bounds %x\n", name, addr, bounds);
} catch (AltosNoSymbol ns) {
if (name_required(name))
throw (ns);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosRotation extends AltosQuaternion {
private AltosQuaternion rotation;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosRotationRate extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
int b;
byte[] data = new byte[len];
- System.out.printf("read_memory %x %d\n", addr, len);
for (int offset = 0; offset < len; offset += 0x100) {
link.printf("R %x\n", addr + offset);
byte[] reply = link.get_binary_reply(5000, 0x100);
long flash_addr = image.address;
int image_start = 0;
- action("start", 0);
+ action(AltosFlashListener.flash_start, 0);
action(0, image.data.length);
while (remain > 0 && !aborted) {
int this_time = remain;
action(image.data.length - remain, image.data.length);
}
if (!aborted) {
- action("done", 100);
+ action(AltosFlashListener.flash_done, 100);
}
close();
} catch (IOException ie) {
long base = AltosRomconfig.fetch_base(image);
long bounds = AltosRomconfig.fetch_bounds(image);
- System.out.printf("rom base %x bounds %x\n", base, bounds);
+ if (link.debug)
+ System.out.printf("rom base %x bounds %x\n", base, bounds);
return read_hexfile(base, (int) (bounds - base));
} catch (AltosNoSymbol ns) {
return null;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosSpeed extends AltosUnits {
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosState extends AltosDataListener {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosStateName extends AltosUnits {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryCompanion extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryLocation extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
import java.util.HashMap;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryMegaData extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
int orient() { return int8(5); }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryMini2 extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryMini3 extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetryRaw extends AltosTelemetryStandard {
public AltosTelemetryRaw(int[] bytes) throws AltosCRCException {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetrySatellite extends AltosTelemetryStandard {
int channels() { return uint8(5); }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTelemetrySensor extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public abstract class AltosTelemetryStandard extends AltosTelemetry {
public int int8(int off) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTemperature extends AltosUnits {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTime extends AltosUnits {
public double value(double v, boolean imperial_units) { return v; }
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosTimeValue {
public double time;
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_13;
+
+import java.io.*;
+import java.lang.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.net.*;
+import java.text.*;
+
+public class AltosUnitInfo extends Thread {
+ int sn;
+ int rfcal;
+ AltosUnitInfoListener listener;
+ String json_string;
+
+ public int sn() {
+ return sn;
+ }
+
+ public int rfcal() {
+ return rfcal;
+ }
+
+ void add(String line) {
+ if (json_string == null) {
+ json_string = line;
+ } else {
+ json_string = json_string + "\n" + line;
+ }
+ }
+
+ void notify_complete() {
+ rfcal = AltosLib.MISSING;
+
+ if (json_string != null) {
+ System.out.printf("json_string: %s\n", json_string);
+ AltosJson json = AltosJson.fromString(json_string);
+ System.out.printf("json: %s\n", json);
+ String rfcal_string = null;
+ try {
+ AltosJson unitinfo = json.get("unitinfo");
+ rfcal_string = unitinfo.get_string("rfcal", null);
+ if (rfcal_string != null)
+ rfcal = Integer.parseInt(rfcal_string);
+ } catch (NumberFormatException ne) {
+ System.out.printf("mal-formed integer %s\n", rfcal_string);
+ } catch (IllegalArgumentException ie) {
+ System.out.printf("mal-formed json\n");
+ }
+ }
+ listener.notify_unit_info(this);
+ }
+
+ public void run() {
+ try {
+ String format;
+
+ format = System.getenv(AltosLib.unit_info_env);
+ if (format == null)
+ format = AltosLib.unit_info_url;
+
+ String path = String.format(format, sn);
+
+ URL url = new URL(path);
+
+ System.out.printf("URL: %s\n", path);
+
+ URLConnection uc = url.openConnection();
+
+ InputStreamReader in_stream = new InputStreamReader(uc.getInputStream(), AltosLib.unicode_set);
+ BufferedReader in = new BufferedReader(in_stream);
+
+ for (;;) {
+ String line = in.readLine();
+ if (line == null)
+ break;
+ add(line);
+ }
+ } catch (Exception e) {
+ System.out.printf("file exception %s\n", e.toString());
+ } finally {
+ notify_complete();
+ }
+ }
+
+ public AltosUnitInfo(int sn, AltosUnitInfoListener listener) {
+ this.listener = listener;
+ this.sn = sn;
+ this.rfcal = AltosLib.MISSING;
+ start();
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_13;
+
+public interface AltosUnitInfoListener {
+ public abstract void notify_unit_info(AltosUnitInfo unit_info);
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosUnitsListener {
public void units_changed(boolean imperial_units);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosUnknownProduct extends Exception {
public String product;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosUsbId {
public int vid;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosVersion {
public final static String version = "@VERSION@";
-
- public final static String google_maps_api_key = "@GOOGLEKEY@";
-
- public static boolean has_google_maps_api_key() {
- return google_maps_api_key != null && google_maps_api_key.length() > 1;
- }
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public class AltosVoltage extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
public interface AltosWriter {
AltosMapLoader.java \
AltosMapTypeListener.java \
AltosJson.java \
- AltosVersion.java
+ AltosVersion.java \
+ AltosUnitInfo.java \
+ AltosUnitInfoListener.java
JAR=altoslib_$(ALTOSLIB_VERSION).jar
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class Altos extends AltosUILib {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosAscent extends AltosUIFlightTab {
JLabel cur, max;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosCompanionInfo extends JTable implements AltosFlightDisplay {
private AltosFlightInfoTableModel model;
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosConfigFC implements ActionListener {
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosConfigFCUI
extends AltosUIDialog
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosConfigPyroUI
extends AltosUIDialog
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosConfigTD implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosConfigTDUI
extends AltosUIDialog
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosConfigureUI
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosDescent extends AltosUIFlightTab {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
import java.text.*;
import java.util.prefs.*;
import java.util.concurrent.LinkedBlockingQueue;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosFlightStatusTableModel extends AbstractTableModel {
private String[] columnNames = {
package altosui;
import java.awt.event.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosFlightStatusUpdate implements ActionListener {
import javax.swing.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
AltosVoice voice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import java.io.*;
import java.util.concurrent.*;
import java.util.Arrays;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosIdleMonitorListener, DocumentListener {
AltosDevice device;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosIgniteUI
extends AltosUIDialog
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosIgnitor extends AltosUIFlightTab {
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosLanded extends AltosUIFlightTab implements ActionListener {
import java.io.*;
import java.util.concurrent.*;
import java.awt.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosLaunch {
AltosDevice device;
import java.io.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
class FireButton extends JButton {
protected void processMouseEvent(MouseEvent e) {
package altosui;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosPad extends AltosUIFlightTab {
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class AltosUI extends AltosUIFrame implements AltosEepromGrapher {
public AltosVoice voice = new AltosVoice();
FIRMWARE_TMEGA_1_0=$(top_srcdir)/src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx
FIRMWARE_TMEGA_2_0=$(top_srcdir)/src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx
-FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0)
+FIRMWARE_TMEGA_3_0=$(top_srcdir)/src/telemega-v3.0/telemega-v3.0-$(VERSION).ihx
+FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0) $(FIRMWARE_TMEGA_3_0)
FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx
FIRMWARE_EMINI=$(FIRMWARE_EMINI_1_0)
LINUX_EXTRA=altosui-fat
MACOSX_INFO_PLIST=Info.plist
-MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(DOC) ReadMe-Mac.rtf $(MACOSX_ICONS)
+MACOSX_INSTALL=install-macosx
+MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(DOC) ReadMe-Mac.rtf $(MACOSX_ICONS) $(MACOSX_INSTALL)
MACOSX_EXTRA=$(FIRMWARE)
WINDOWS_FILES=$(FAT_FILES) $(FIRMWARE) altos.dll altos64.dll $(top_srcdir)/altusmetrum.inf $(top_srcdir)/altusmetrum.cat $(WINDOWS_ICONS)
-rm -rf macosx
mkdir macosx
cp -a AltosUI.app macosx/
- cp -a ReadMe-Mac.rtf macosx/ReadMe.rtf
+ cp -a $(MACOSX_INSTALL) macosx
+ cp -a ReadMe-Mac.rtf macosx/ReadMe-AltosUI.rtf
mkdir -p macosx/Doc
cp -a $(DOC) macosx/Doc
cp -p Info.plist macosx/AltosUI.app/Contents
{\rtf1\ansi\deff3\adeflang1025
-{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset128 Liberation Serif{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset128 Arial;}{\f5\fnil\fprq2\fcharset128 SimSun;}{\f6\fnil\fprq2\fcharset128 Raghindi;}{\f7\fnil\fprq0\fcharset128 Raghindi;}}
-{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
-{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033 Normal;}
+{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq2\fcharset0 Arial;}{\f5\froman\fprq2\fcharset0 Helvetica LT Std;}{\f6\froman\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f7\fnil\fprq2\fcharset0 SimSun;}{\f8\fnil\fprq2\fcharset0 Helvetica LT Std;}{\f9\fnil\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f10\fnil\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+{\stylesheet{\s0\snext0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033 Normal;}
{\*\cs15\snext15 Numbering Symbols;}
-{\s16\sbasedon0\snext17\sb240\sa120\keepn\hich\af5\dbch\af6\afs28\loch\f4\fs28 Heading;}
-{\s17\sbasedon0\snext17\sb0\sa120 Text body;}
-{\s18\sbasedon17\snext18\sb0\sa120\dbch\af7 List;}
-{\s19\sbasedon0\snext19\sb120\sa120\noline\i\dbch\af7\afs24\ai\fs24 Caption;}
-{\s20\sbasedon0\snext20\noline\dbch\af7 Index;}
+{\s16\sbasedon0\snext17\ql\nowidctlpar\hyphpar0\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f4\fs28\lang1033 Heading;}
+{\s17\sbasedon0\snext17\sl276\slmult1\ql\nowidctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f3\fs24\lang1033 Text Body;}
+{\s18\sbasedon17\snext18\sl276\slmult1\ql\nowidctlpar\hyphpar0\sb0\sa120\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f3\fs24\lang1033 List;}
+{\s19\sbasedon0\snext19\ql\nowidctlpar\hyphpar0\sb120\sa120\ltrpar\cf0\i\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f3\fs24\lang1033 Caption;}
+{\s20\sbasedon0\snext20\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f3\fs24\lang1033 Index;}
+{\s21\sbasedon0\snext21\ql\nowidctlpar\hyphpar0\sb0\sa120\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f3\fs24\lang1033 Text body;}
}{\*\listtable{\list\listtemplateid1
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'00);}{\levelnumbers\'01;}\fi-360\li720}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'01.;}{\levelnumbers\'01;}\fi-360\li1080}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'07.;}{\levelnumbers\'01;}\fi-360\li3240}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'08.;}{\levelnumbers\'01;}\fi-360\li3600}\listid1}
{\list\listtemplateid2
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-432\li432}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-576\li576}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-720\li720}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-864\li864}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-1008\li1008}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-1152\li1152}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-1296\li1296}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-1440\li1440}
-{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow0{\leveltext \'00;}{\levelnumbers;}\fi-1584\li1584}\listid2}
-}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}{\info{\creatim\yr2013\mo1\dy6\hr13\min7}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern3500}}\deftab709
-
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}\listid2}
+}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}{\*\generator LibreOffice/6.1.2.1$Linux_X86_64 LibreOffice_project/10$Build-1}{\info{\creatim\yr2013\mo1\dy6\hr13\min7}{\revtim\yr2018\mo10\dy5\hr19\min22}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab709
+\hyphauto0\viewscale150
{\*\pgdsctbl
-{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Default;}}
-\formshade\paperh15840\paperw12240\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
-\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
+{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Default Style;}}
+\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
+{\*\ftnsep\chftnsep}\pgndec\pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
Installing AltOS software for Mac OS X Computers}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
-}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af7\langfe1081\dbch\af9\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
The AltOS distribution for Mac OS X consists of:}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
-}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 1)\tab}\ilvl0\ls1 \li720\ri0\lin720\rin0\fi-360{\rtlch \ltrch\loch
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 1)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
The AltosUI application}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 2)\tab}\ilvl0\ls1 \li720\ri0\lin720\rin0\fi-360{\rtlch \ltrch\loch
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 2)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
Current AltOS firmware for Altus Metrum products}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
-}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
-Install the AltosUI application by dragging it to your Applications folder (or wherever else you want to install it).}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
-}
-\par \pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\hich\af5\langfe2052\dbch\af6\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch
-The AltOS firmware can be used to update your Altus Metrum products to the latest firmware version, you can copy it to your disk if you like, or simply use it directly from the installation disk image.}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+Install the AltosUI application by control-clicking the install-macosx script and selecting \u8220\'93Open\u8221\'94 from the menu. This will display a dialog asking if you are sure you want to open it. Select \u8220\'93Open\u8221\'94 from the dialog to execute the script. This will install the software, documentation and firmware in your home Applications/AltOS folder. You can move it afte}{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+r}{\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+wards if you choose.}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af7\langfe1081\dbch\af8\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af7\langfe1081\dbch\af9\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+Thanks for choosing AltusMetrum products!}
\par }
\ No newline at end of file
File "../src/telebt-v4.0/telebt-v4.0-${VERSION}.ihx"
File "../src/telemega-v1.0/telemega-v1.0-${VERSION}.ihx"
File "../src/telemega-v2.0/telemega-v2.0-${VERSION}.ihx"
+ File "../src/telemega-v3.0/telemega-v3.0-${VERSION}.ihx"
File "../src/easymini-v1.0/easymini-v1.0-${VERSION}.ihx"
File "../src/easymini-v2.0/easymini-v2.0-${VERSION}.ihx"
File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx"
--- /dev/null
+#!/bin/sh
+dir=`dirname "$0"`
+cd "$dir"
+mkdir -p ~/Applications/AltOS
+find ~/Applications/AltOS -type d -print0 | xargs -0 chmod +w
+cp -f -a * ~/Applications/AltOS
+cd ~/Applications/AltOS
+chmod +w *
+xattr -c *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosBTDevice extends altos_bt_device implements AltosDevice {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
AltosBTDevice current;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosBTKnown implements Iterable<AltosBTDevice> {
LinkedList<AltosBTDevice> devices = new LinkedList<AltosBTDevice>();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.basic.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> {
LinkedBlockingQueue<AltosBTDevice> found_devices;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosCSVUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class AltosEditFreqUI extends AltosUIDialog implements ActionListener {
Frame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosDataChooser extends JFileChooser {
JFrame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import libaltosJNI.*;
public abstract boolean matchProduct(int product);
public abstract String getErrorString();
public SWIGTYPE_p_altos_file open();
+ public abstract boolean equals(Object obj);
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
import java.awt.*;
public Frame frame;
public int product;
public JPanel buttonPane;
+ private Timer timer;
+ AltosDevice[] devices;
public AltosDevice getValue() {
return value;
public abstract AltosDevice[] devices();
public void update_devices() {
- AltosDevice[] devices = devices();
+ AltosDevice selected = list.getSelectedValue();
+
+ devices = devices();
list.setListData(devices);
+ for (AltosDevice d : devices) {
+ if (d.equals(selected)) {
+ list.setSelectedValue(d, true);
+ break;
+ }
+ }
select_button.setEnabled(devices.length > 0);
}
frame = in_frame;
value = null;
- AltosDevice[] devices = devices();
-
cancel_button = new JButton("Cancel");
cancel_button.setActionCommand("cancel");
cancel_button.addActionListener(this);
select_button = new JButton("Select");
select_button.setActionCommand("select");
select_button.addActionListener(this);
- if (devices.length == 0)
- select_button.setEnabled(false);
+ select_button.setEnabled(false);
getRootPane().setDefaultButton(select_button);
list = new JList<AltosDevice>(devices) {
contentPane.add(buttonPane, BorderLayout.PAGE_END);
//Initialize values.
+ update_devices();
if (devices != null && devices.length != 0)
list.setSelectedValue(devices[0], true);
pack();
setLocationRelativeTo(location);
+
+ timer = new Timer(1000, new ActionListener () {
+ public void actionPerformed(ActionEvent evt) {
+ update_devices();
+ }
+ });
+
+ addComponentListener(new ComponentListener() {
+ public void componentShown(ComponentEvent e) {
+ timer.start();
+ }
+ public void componentMoved(ComponentEvent e) {
+ }
+ public void componentResized(ComponentEvent e) {
+ }
+ public void componentHidden(ComponentEvent e) {
+ timer.stop();
+ }
+ });
+
}
//Handle clicks on the Set and Cancel buttons.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosDisplayThread extends Thread {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosEepromDelete implements Runnable {
AltosEepromList flights;
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public interface AltosEepromGrapher {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosEepromManage implements ActionListener {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class result_holder {
static int result;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class AltosEepromItem implements ActionListener {
AltosEepromLog log;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosFlashUI
extends AltosUIDialog
JOptionPane.ERROR_MESSAGE);
setVisible(false);
dispose();
- } else if (cmd.equals("done")) {
+ } else if (cmd.equals(AltosFlashListener.flash_done)) {
setVisible(false);
dispose();
- } else if (cmd.equals("start")) {
+ } else if (cmd.equals(AltosFlashListener.flash_start)) {
setVisible(true);
} else {
pbar.setValue(e.getID());
}
boolean rom_config_matches (AltosRomconfig a, AltosRomconfig b) {
+ if (a == null || b == null)
+ return (a == null && b == null);
+
+ if (!a.valid || !b.valid)
+ return false;
+
if (a.usb_id != null && b.usb_id != null &&
(a.usb_id.vid != b.usb_id.vid ||
a.usb_id.pid != b.usb_id.pid))
AltosRomconfig new_config;
if (!rom_config_matches(existing_config, image_config)) {
+ int ret;
+ if (existing_config == null || !existing_config.valid) {
+ ret = JOptionPane.showConfirmDialog(this,
+ String.format("Cannot determine target device type\nImage is %04x:%04x %s\nFlash anyways?",
+ image_config.usb_id.vid,
+ image_config.usb_id.pid,
+ image_config.usb_product),
+ "Unknown Target Device",
+ JOptionPane.YES_NO_OPTION);
+ } else {
+ ret = JOptionPane.showConfirmDialog(this,
+ String.format("Device is %04x:%04x %s\nImage is %04x:%04x %s\nFlash anyways?",
+ existing_config.usb_id.vid,
+ existing_config.usb_id.pid,
+ existing_config.usb_product,
+ image_config.usb_id.vid,
+ image_config.usb_id.pid,
+ image_config.usb_product),
+ "Image doesn't match Device",
+ JOptionPane.YES_NO_OPTION);
+ }
+ if (ret != JOptionPane.YES_OPTION)
+ return false;
+ }
+
+ if (existing_config.radio_calibration_broken) {
int ret = JOptionPane.showConfirmDialog(this,
- String.format("Device is %04x:%04x %s\nImage is %04x:%04x %s\nFlash anyways?",
- existing_config.usb_id.vid,
- existing_config.usb_id.pid,
- existing_config.usb_product,
- image_config.usb_id.vid,
- image_config.usb_id.pid,
- image_config.usb_product),
- "Image doesn't match Device",
+ String.format("Radio calibration value %d may be incorrect\nFlash anyways?",
+ existing_config.radio_calibration),
+ "Radio Calibration Invalid",
JOptionPane.YES_NO_OPTION);
if (ret != JOptionPane.YES_OPTION)
return false;
}
+
new_config = AltosRomconfigUI.show(frame, existing_config);
if (new_config == null)
return false;
device.toShortString()),
"Device in use",
JOptionPane.ERROR_MESSAGE);
- } else if (e instanceof IOException) {
+ } else {
JOptionPane.showMessageDialog(frame,
e.getMessage(),
file.toString(),
flash_task flasher;
- private boolean open_device() throws InterruptedException {
- try {
- link = new AltosSerial(device);
- if (is_pair_programmed())
- return true;
- if (link == null)
- throw new IOException(String.format("%s: open failed", device.toShortString()));
+ class open_task implements Runnable {
+ AltosDevice device;
+ Thread t;
+ open_dialog dialog;
- while (!link.is_loader()) {
- link.to_loader();
+ public void do_exception(final Exception e) {
+ SwingUtilities.invokeLater(
+ new Runnable() {
+ public void run() {
+ try { dialog.open_exception(e); } catch (Exception ex) { }
+ }
+ });
+ }
- java.util.List<AltosDevice> devices = null;
+ public void do_success(final AltosLink link) {
+ SwingUtilities.invokeLater(
+ new Runnable() {
+ public void run() {
+ try { dialog.open_success(link); } catch (Exception ex) { }
+ }
+ });
+ }
- for (int tries = 0; tries < 10; tries++) {
- Thread.sleep(100);
- devices = AltosUSBDevice.list(AltosLib.product_altusmetrum);
- if (devices.size() != 0)
- break;
- }
+ public void do_failure() {
+ SwingUtilities.invokeLater(
+ new Runnable() {
+ public void run() {
+ try { dialog.open_failure(); } catch (Exception ex) { }
+ }
+ });
+ }
+
+ public void do_cancel() {
+ SwingUtilities.invokeLater(
+ new Runnable() {
+ public void run() {
+ try { dialog.open_cancel(); } catch (Exception ex) { }
+ }
+ });
+ }
+
+ public void run () {
+ try {
+ AltosLink link = null;
+
+ for (;;) {
+ System.out.printf("Attempting to open %s\n", device.toShortString());
+
+ link = new AltosSerial(device);
- if (devices.size() == 1)
- device = devices.get(0);
- else {
- device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum);
- if (device == null)
- return false;
+ if (link == null)
+ throw new IOException(String.format("%s: open failed",
+ device.toShortString()));
+
+ /* See if the link is usable already */
+ if (is_pair_programmed() || link.is_loader()) {
+ System.out.printf("Device ready for use\n");
+ do_success(link);
+ return;
+ }
+
+ java.util.List<AltosDevice> prev_devices =
+ AltosUSBDevice.list(AltosLib.product_altusmetrum);
+
+ /* Nope, switch to loader and
+ * wait for it to re-appear
+ */
+
+ System.out.printf("Switch to loader\n");
+
+ link.to_loader();
+
+ /* This is a bit fragile, but
+ * I'm not sure what else to
+ * do other than ask the user.
+ *
+ * Search for a device which
+ * wasn't there before we
+ * asked the target to switch
+ * to loader mode
+ */
+
+ device = null;
+ for (;;) {
+ Thread.sleep(100);
+ java.util.List<AltosDevice> devices =
+ AltosUSBDevice.list(AltosLib.product_altusmetrum);
+
+ for (AltosDevice d : devices) {
+ boolean matched = false;
+ System.out.printf("\tfound device %s\n", d.toShortString());
+ for (AltosDevice p : prev_devices)
+ if (d.equals(p)) {
+ matched = true;
+ break;
+ }
+ if (!matched) {
+ System.out.printf("Identified new device %s\n", d.toShortString());
+ device = d;
+ break;
+ }
+ }
+ if (device != null)
+ break;
+ }
}
- link = new AltosSerial(device);
+ } catch (AltosSerialInUseException ee) {
+ do_exception(ee);
+ } catch (FileNotFoundException fe) {
+ do_exception(fe);
+ } catch (IOException ie) {
+ do_exception (ie);
+ } catch (InterruptedException ie) {
}
- return true;
- } catch (AltosSerialInUseException ee) {
- exception(ee);
- } catch (FileNotFoundException fe) {
- exception(fe);
- } catch (IOException ie) {
- exception (ie);
}
- return false;
+
+ public void cancel() {
+ t.interrupt();
+ }
+
+ public open_task(AltosDevice device, open_dialog dialog) {
+ this.device = device;
+ this.dialog = dialog;
+ t = new Thread(this);
+ t.start();
+ }
+ }
+
+ class open_dialog
+ extends AltosUIDialog
+ implements ActionListener
+ {
+ AltosUIFrame owner;
+
+ private JLabel opening_label;
+ private JButton cancel_button;
+
+ boolean done = false;
+
+ AltosLink link = null;
+
+ open_task open = null;
+
+ public void open_exception(Exception e) {
+ System.out.printf("open_exception\n");
+ setVisible(false);
+ exception(e);
+ done = true;
+ }
+
+ public void open_success(AltosLink link) {
+ System.out.printf("open_success\n");
+ setVisible(false);
+ this.link = link;
+ done = true;
+ }
+
+ public void open_failure() {
+ System.out.printf("open_failure\n");
+ setVisible(false);
+ done = true;
+ }
+
+ public void open_cancel() {
+ System.out.printf("open_cancel\n");
+ setVisible(false);
+ done = true;
+ }
+
+ public AltosLink do_open(open_task open) throws InterruptedException {
+ this.open = open;
+ setVisible(true);
+ return link;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+
+ if (cmd.equals("cancel"))
+ if (open != null)
+ open.cancel();
+ done = true;
+ setVisible(false);
+ }
+
+ public open_dialog(AltosUIFrame in_owner) {
+ super(in_owner, "Open Flash Target Device", true);
+ owner = in_owner;
+
+ Container pane = getContentPane();
+ GridBagConstraints c = new GridBagConstraints();
+ Insets i = new Insets(4,4,4,4);
+
+
+ pane.setLayout(new GridBagLayout());
+
+ opening_label = new JLabel("Opening Device");
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = i;
+ c.weightx = 0;
+ c.weighty = 0;
+
+ c.gridx = 0;
+ c.gridy = 0;
+
+ pane.add(opening_label, c);
+
+ cancel_button = new JButton("Cancel");
+ cancel_button.addActionListener(this);
+ cancel_button.setActionCommand("cancel");
+
+ c.gridy = 1;
+ pane.add(cancel_button, c);
+ pack();
+ setLocationRelativeTo(owner);
+ }
+ }
+
+ private boolean open_device() throws InterruptedException {
+
+ open_dialog dialog = new open_dialog(frame);
+
+ open_task open = new open_task(device, dialog);
+
+ link = dialog.do_open(open);
+
+ return link != null;
}
/*
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.table.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosFlightStatsTable extends JComponent implements AltosFontListener {
GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosInfoTable extends JTable implements AltosFlightDisplay, HierarchyListener {
private AltosFlightInfoTableModel model;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public interface AltosPositionListener {
public void position_changed(int position);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosRomconfigUI
extends AltosUIDialog
JButton cancel;
/* Build the UI using a grid bag */
- public AltosRomconfigUI(JFrame in_owner) {
- super (in_owner, "Configure TeleMetrum Rom Values", true);
+ public AltosRomconfigUI(JFrame frame, AltosRomconfig config) {
+ super (frame, "Configure Rom Values", true);
- owner = in_owner;
+ owner = frame;
GridBagConstraints c;
Insets il = new Insets(4,4,4,4);
pane = getContentPane();
pane.setLayout(new GridBagLayout());
+ int y = 0;
+
/* Serial */
c = new GridBagConstraints();
- c.gridx = 0; c.gridy = 0;
+ c.gridx = 0; c.gridy = y;
c.gridwidth = 3;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.LINE_START;
pane.add(serial_label, c);
c = new GridBagConstraints();
- c.gridx = 3; c.gridy = 0;
+ c.gridx = 3; c.gridy = y;
c.gridwidth = 3;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
serial_value = new JTextField("00000000");
pane.add(serial_value, c);
- /* Radio calibration value */
- c = new GridBagConstraints();
- c.gridx = 0; c.gridy = 1;
- c.gridwidth = 3;
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = il;
- c.ipady = 5;
- radio_calibration_label = new JLabel("Radio Calibration:");
- pane.add(radio_calibration_label, c);
-
- c = new GridBagConstraints();
- c.gridx = 3; c.gridy = 1;
- c.gridwidth = 3;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.weightx = 1;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = ir;
- c.ipady = 5;
- radio_calibration_value = new JTextField("00000000");
- pane.add(radio_calibration_value, c);
+ y++;
+
+ if (AltosLib.has_radio(config.usb_id.pid)) {
+ /* Radio calibration value */
+ c = new GridBagConstraints();
+ c.gridx = 0; c.gridy = y;
+ c.gridwidth = 3;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ radio_calibration_label = new JLabel("Radio Calibration:");
+ pane.add(radio_calibration_label, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 3; c.gridy = y;
+ c.gridwidth = 3;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = ir;
+ c.ipady = 5;
+ radio_calibration_value = new JTextField("00000000");
+ pane.add(radio_calibration_value, c);
+
+ y++;
+ }
/* Buttons */
c = new GridBagConstraints();
- c.gridx = 0; c.gridy = 2;
+ c.gridx = 0; c.gridy = y;
c.gridwidth = 3;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.CENTER;
ok.setActionCommand("ok");
c = new GridBagConstraints();
- c.gridx = 3; c.gridy = 2;
+ c.gridx = 3; c.gridy = y;
c.gridwidth = 3;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.CENTER;
cancel.addActionListener(this);
cancel.setActionCommand("cancel");
+ y++;
+
pack();
setLocationRelativeTo(owner);
- }
-
- public AltosRomconfigUI(JFrame frame, AltosRomconfig config) {
- this(frame);
set(config);
}
}
int radio_calibration() {
+ if (radio_calibration_value == null)
+ return 0;
+
return Integer.parseInt(radio_calibration_value.getText());
}
void set_radio_calibration(int calibration) {
+ if (radio_calibration_value == null)
+ return;
radio_calibration_value.setText(String.format("%d", calibration));
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class AltosScanResult {
String callsign;
* Deal with TeleDongle on a serial port
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import libaltosJNI.*;
/*
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public class AltosSerialInUseException extends Exception {
public AltosDevice device;
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public interface AltosShapeListener {
void set_shapes_visible(boolean visible);
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUIAccelCal
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class DelegatingRenderer implements ListCellRenderer<Object> {
constraints(0, 3));
row++;
- pane.add(new JLabel (String.format("AltOS version %s (%smaps key)",
- AltosVersion.version,
- AltosVersion.has_google_maps_api_key() ? "" : "no ")),
+ pane.add(new JLabel (String.format("AltOS version %s",
+ AltosVersion.version)),
constraints(0, 3));
row++;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public class AltosUIDataMissing extends Exception {
public int id;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public interface AltosUIDataPoint {
public abstract double x() throws AltosUIDataMissing;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public interface AltosUIDataSet {
public abstract String name();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public abstract class AltosUIFlightTab extends JComponent implements AltosFlightDisplay, HierarchyListener {
public GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUIFreqList extends JComboBox<AltosFrequency> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_12;
+package org.altusmetrum.altoslib_13;
import javax.swing.*;
import javax.imageio.ImageIO;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public abstract class AltosUIIndicator implements AltosFontListener, AltosUnitsListener {
JLabel label;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUILib extends AltosLib {
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
public interface AltosUIListener {
public void ui_changed(String look_and_feel);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.concurrent.*;
import javax.imageio.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosMapInterface {
}
private boolean is_drag_event(MouseEvent e) {
- return e.getModifiers() == InputEvent.BUTTON1_MASK;
+ return e.getModifiersEx() == InputEvent.BUTTON1_DOWN_MASK;
}
/* MouseMotionListener methods */
if (image != null) {
g.drawImage(image, point.x, point.y, null);
+/*
+ * Useful when debugging map fetching problems
+ *
+ String message = String.format("%.6f %.6f", center.lat, center.lon);
+ g.setFont(tile_font);
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ Rectangle2D bounds = tile_font.getStringBounds(message, g.getFontRenderContext());
+
+ float x = px_size / 2.0f;
+ float y = px_size / 2.0f;
+ x = x - (float) bounds.getWidth() / 2.0f;
+ y = y + (float) bounds.getHeight() / 2.0f;
+ g.setColor(Color.RED);
+ g.drawString(message, (float) point_double.x + x, (float) point_double.y + y);
+*/
} else {
g.setColor(Color.GRAY);
g.fillRect(point.x, point.y, px_size, px_size);
message = "Internal error";
break;
case AltosMapTile.failed:
- message = "Network error, check connection";
+ message = "Network error";
break;
case AltosMapTile.forbidden:
- message = "Too many requests, try later";
+ message = "Outside of known launch areas";
break;
}
if (message != null && tile_font != null) {
JLabel zoom_label;
public void set_maptype(int type) {
+/*
map.set_maptype(type);
maptype_combo.setSelectedIndex(type);
+*/
}
/* AltosUIMapPreload functions */
/* internal layout bits */
private GridBagLayout layout = new GridBagLayout();
+/*
JComboBox<String> maptype_combo;
+*/
MapView view;
c.weighty = 0;
add(zoom_out, c);
+/*
maptype_combo = new JComboBox<String>(map.maptype_labels);
maptype_combo.setEditable(false);
c.weightx = 0;
c.weighty = 0;
add(maptype_combo, c);
-
+*/
map = new AltosMap(this);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.net.URL;
import java.net.URLConnection;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
class AltosUIMapPos extends Box implements ActionListener {
AltosUIMapPreload preload;
JToggleButton load_button;
JButton close_button;
+/*
JCheckBox[] maptypes = new JCheckBox[AltosMap.maptype_terrain - AltosMap.maptype_hybrid + 1];
+*/
JComboBox<Integer> min_zoom;
JComboBox<Integer> max_zoom;
private int all_types() {
+/*
int all_types = 0;
for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
if (maptypes[t].isSelected())
all_types |= (1 << t);
return all_types;
+*/
+ return 1 << AltosMap.maptype_hybrid;
}
void center_map(double latitude, double longitude) {
pane.add(close_button, c);
+/*
JLabel types_label = new JLabel("Map Types");
c.gridx = 2;
c.gridwidth = 2;
c.gridy = (type & 1) + 3;
pane.add(maptypes[type], c);
}
+*/
JLabel min_zoom_label = new JLabel("Minimum Zoom");
c.gridx = 4;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.*;
import java.awt.Component;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUIPreferences extends AltosPreferences {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.File;
import java.util.prefs.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import javax.swing.filechooser.FileSystemView;
public class AltosUIPreferencesBackend extends AltosPreferencesBackend {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUIRateList extends JComboBox<String> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.util.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class AltosUITelemetryList extends JComboBox<String> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public abstract class AltosUIVoltageIndicator extends AltosUIUnitsIndicator {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.util.*;
import libaltosJNI.*;
return false;
}
+ public int hashCode() {
+ return getVendor() ^ getProduct() ^ getSerial() ^ getPath().hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o == null)
+ return false;
+
+ if (!(o instanceof AltosUSBDevice))
+ return false;
+ AltosUSBDevice other = (AltosUSBDevice) o;
+
+ return getVendor() == other.getVendor() &&
+ getProduct() == other.getProduct() &&
+ getSerial() == other.getSerial() &&
+ getPath().equals(other.getPath());
+ }
+
static public java.util.List<AltosDevice> list(int product) {
if (!AltosUILib.load_library())
return null;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
+++ /dev/null
-/*
- * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altosuilib_12;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-import javax.swing.event.MouseInputAdapter;
-
-class GrabNDrag extends MouseInputAdapter {
- private JComponent scroll;
- private Point startPt = new Point();
-
- public GrabNDrag(JComponent scroll) {
- this.scroll = scroll;
- scroll.addMouseMotionListener(this);
- scroll.addMouseListener(this);
- scroll.setAutoscrolls(true);
- }
-
- public static boolean grab_n_drag(MouseEvent e) {
- return e.getModifiers() == InputEvent.BUTTON1_MASK;
- }
-
- public void mousePressed(MouseEvent e) {
- if (grab_n_drag(e))
- startPt.setLocation(e.getPoint());
- }
- public void mouseDragged(MouseEvent e) {
- if (grab_n_drag(e)) {
- int xd = e.getX() - startPt.x;
- int yd = e.getY() - startPt.y;
-
- Rectangle r = scroll.getVisibleRect();
- r.x -= xd;
- r.y -= yd;
- scroll.scrollRectToVisible(r);
- }
- }
-}
altosuilibdir = $(datadir)/java
altosuilib_JAVA = \
- GrabNDrag.java \
AltosDevice.java \
AltosDeviceDialog.java \
AltosPositionListener.java \
*/
-package org.altusmetrum.altosuilib_12;
+package org.altusmetrum.altosuilib_13;
import java.lang.reflect.*;
import java.util.HashMap;
--- /dev/null
+#!/bin/sh
+
+VERSION=4.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleBT
+
+ALTOS_FILE=$REPO/telebt-v$VERSION-*.elf
+
+if [ -x /usr/bin/ao-usbload ]; then
+ USBLOAD=/usr/bin/ao-usbload
+else
+ echo "Can't find ao-usbload! Aborting."
+ exit 1
+fi
+
+dev_serial=`ao-list | awk '/'"$PRODUCT"'-v'"$VERSION"'/ { printf("%s %s\n", $3, $2); exit(0); }'`
+dev=`echo $dev_serial | awk '{print $1;}'`
+serial=`echo $dev_serial | awk '{print $2;}'`
+
+case "$dev" in
+/dev/tty*)
+ ;;
+*)
+ echo 'No '"$PRODUCT"'-v'"$VERSION"' found'
+ exit 1
+ ;;
+esac
+
+rfcal=`wget -O - -q 'http://altusmetrum.org/cgi-bin/unitinfo.cgi?sn='$serial | jq '.unitinfo.rfcal | tonumber'`
+
+case $? in
+0)
+ ;;
+*)
+ echo "Fetch rfcal for $serial failed"
+ exit 1
+ ;;
+esac
+
+case "$rfcal" in
+[0-9]*)
+ ;;
+*)
+ echo "Serial $serial: invalid rfcal $rfcal"
+ ;;
+esac
+
+echo "$PRODUCT"'-v'"$VERSION $serial $dev rfcal $rfcal"
+
+$USBLOAD --cal=$rfcal --tty=$dev $ALTOS_FILE || exit 1
+
+echo "$PRODUCT"'-v'"$VERSION $serial $dev is ready to ship"
[\--tty \fItty-device\fP]
[\-D \fIaltos-device\fP]
[\--device \fIaltos-device\fP]
+[\-v] [\--verbose]
+[\-n] [\--nosave]
+[\-o \fIcal-value-output-file\fP]
+[\--output \fIcal-value-output-file\fP]
.SH DESCRIPTION
.I ao-cal-freq
drives the frequency calibration process and saves the result.
Leaving out the product name will cause the tool to select a suitable
product, leaving out the serial number will cause the tool to match
one of the available devices.
+.TP
+\-o cal-value-output-file | --output cal-value-output-file
+Writes the resulting calibration value to the specified file.
+.TP
+\-n | --nosave
+Inhibits saving the calibration value on the device. Necessary for
+devices which don't have on-board configuration storage.
+.TP
+\-v | --verbose
+Makes
+.I ao-cal-freq
+chatty about communication with the target device.
.SH USAGE
.I ao-cal-freq
opens the target device, interactively calibrates the frequency, then
-shows the resulting calibration values and saves them to configuration
-memory.
+shows the resulting calibration values and (optionally) saves them to
+configuration memory and/or a file.
.SH AUTHOR
Keith Packard
static const struct option options[] = {
{ .name = "tty", .has_arg = 1, .val = 'T' },
{ .name = "device", .has_arg = 1, .val = 'D' },
- { .name = "raw", .has_arg = 0, .val = 'r' },
{ .name = "verbose", .has_arg = 0, .val = 'v' },
+ { .name = "output", .has_arg = 1, .val = 'o' },
+ { .name = "nosave", .has_arg = 0, .val = 'n' },
{ 0, 0, 0, 0},
};
static void usage(char *program)
{
- fprintf(stderr, "usage: %s [--verbose] [--device=<device>] [-tty=<tty>]\n", program);
+ fprintf(stderr, "usage: %s [--verbose] [--nosave] [--device=<device>] [-tty=<tty>] [--output=<cal-value-file>]\n", program);
exit(1);
}
}
int
-do_cal(char *tty) {
+do_save(struct cc_usb *usb)
+{
+ int ret = 0;
+
+ printf("Saving calibration to device\n");
+ cc_usb_printf(usb, "c w\nv\n");
+ for (;;) {
+ char line[512];
+
+ cc_usb_getline(usb, line, sizeof (line));
+ if (strstr(line, "Nothing to save"))
+ ret = 1;
+ if (strstr(line, "Saved"))
+ ret = 1;
+ if (strstr(line, "software-version"))
+ break;
+ }
+ if (!ret) {
+ printf("Calibration save failed\n");
+ }
+ return ret;
+}
+
+int
+do_output(char *output, int cur_cal)
+{
+ printf ("Saving calibration value to file \"%s\"\n", output);
+
+ FILE *out = fopen(output, "w");
+ int ret = 1;
+
+ if (!out) {
+ perror(output);
+ return 0;
+ }
+
+ if (fprintf(out, "%d\n", cur_cal) < 0) {
+ perror("fprintf");
+ ret = 0;
+ }
+ if (fflush(out) != 0) {
+ perror("fflush");
+ ret = 0;
+ }
+ if (fclose(out) != 0) {
+ perror("fclose");
+ ret = 0;
+ }
+ return ret;
+}
+
+int
+do_cal(char *tty, int save, char *output)
+{
struct cc_usb *usb = NULL;
struct flash *b;
char line[1024];
int cur_cal;
int new_cal;
int ret = 1;
+ int changed = 0;
for(;;) {
usb = cc_usb_open(tty);
- if (!usb)
- exit(1);
+ if (!usb) {
+ fprintf(stderr, "failed to open device\n");
+ ret = 0;
+ break;
+ }
cc_usb_printf(usb, "E 0\n");
- cc_usb_sync(usb);
- cc_usb_printf(usb, "C 1\n");
- cc_usb_sync(usb);
-
- printf("Generating RF carrier. Please enter measured frequency [enter for done]: ");
- fflush(stdout);
- fgets(line, sizeof (line) - 1, stdin);
- cc_usb_printf(usb, "C 0\n");
- cc_usb_sync(usb);
-
- measured_freq = strtod(line, &line_end);
- if (line_end == line)
- break;
-
b = flash(usb);
cur_cal_words = find_flash(b, "Radio cal:");
cur_freq_words = find_flash(b, "Frequency:");
if (!cur_cal_words || !cur_freq_words) {
- printf("no response\n");
+ fprintf(stderr, "no response\n");
ret = 0;
break;
}
cur_freq = atoi(cur_freq_words[1]);
printf ("Current radio calibration %d\n", cur_cal);
- printf ("Current radio frequency: %d\n", cur_freq);
+ printf ("Current radio frequency: %7.3f\n", cur_freq / 1000.0);
+
+ cc_usb_sync(usb);
+ cc_usb_printf(usb, "C 1\n");
+ cc_usb_sync(usb);
+
+ printf("Generating RF carrier. Please enter measured frequency [enter for done]: ");
+ fflush(stdout);
+ fgets(line, sizeof (line) - 1, stdin);
+ cc_usb_printf(usb, "C 0\n");
+ cc_usb_sync(usb);
+ measured_freq = strtod(line, &line_end);
+ if (line_end == line)
+ break;
new_cal = floor ((((double) cur_freq / 1000.0) / measured_freq) * cur_cal + 0.5);
- printf ("Programming flash with cal value %d\n", new_cal);
+ if (new_cal == cur_cal) {
+ printf("Calibration value %d unchanged\n", cur_cal);
+ } else {
+ printf ("Setting cal value %d\n", new_cal);
- cc_usb_printf (usb, "c f %d\nc w\n", new_cal);
- cc_usb_sync(usb);
+ cc_usb_printf (usb, "c f %d\n", new_cal);
+ changed = 1;
+ cc_usb_sync(usb);
+ }
cc_usb_close(usb);
}
- if (usb)
+ if (usb) {
+ if (ret && save) {
+ if (changed) {
+ if (!do_save(usb))
+ ret = 0;
+ } else {
+ printf("Calibration unchanged, not saving\n");
+ }
+ }
+ if (ret && output) {
+ if (!do_output(output, cur_cal))
+ ret = 0;
+ }
cc_usb_close(usb);
+ }
return ret;
}
char *tty = NULL;
int success;
int verbose = 0;
+ int save = 1;
int ret = 0;
int expected_size;
+ char *output = NULL;
- while ((c = getopt_long(argc, argv, "vrT:D:c:s:", options, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "vnT:D:o:", options, NULL)) != -1) {
switch (c) {
case 'T':
tty = optarg;
case 'v':
verbose++;
break;
+ case 'n':
+ save = 0;
+ break;
+ case 'o':
+ output = optarg;
+ break;
default:
usage(argv[0]);
break;
}
ao_verbose = verbose;
-
- if (verbose > 1)
+ if (verbose)
ccdbg_add_debug(CC_DEBUG_BITBANG);
if (!tty)
if (!tty)
tty="/dev/ttyACM0";
- if (!do_cal(tty))
+ if (!do_cal(tty, save, output))
ret = 1;
+ return ret;
}
-bin_SCRIPTS=ao-flash-stm ao-flash-lpc ao-flash-stm32f0x
+bin_SCRIPTS=ao-flash-stm ao-flash-lpc ao-flash-stm32f0x ao-reset-lpc
-man_MANS = ao-flash-stm.1 ao-flash-lpc.1 ao-flash-stm32f0x.1
+man_MANS = ao-flash-stm.1 ao-flash-lpc.1 ao-flash-stm32f0x.1 ao-reset-lpc.1
--- /dev/null
+#!/bin/sh
+cmds=/tmp/flash$$
+trap "rm $cmds" 0 1 15
+echo "reset" > $cmds
+openocd \
+ -f interface/stlink-v2.cfg \
+ -f target/lpc11xx.cfg \
+ -f $cmds \
+ -c shutdown
--- /dev/null
+.\"
+.\" Copyright © 2018 Bdale Garbee <bdale@gag.com>
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+.\" General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License along
+.\" with this program; if not, write to the Free Software Foundation, Inc.,
+.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+.\"
+.\"
+.TH AO-RESET-LPC 1 "ao-reset-lpc" ""
+.SH NAME
+ao-reset-lpc \- reset an LPC11U14-based AltOS device using openocd
+.SH SYNOPSIS
+.B "ao-reset-lpc"
+.SH DESCRIPTION
+.I ao-reset-lpc
+resets the target device.
+.SH USAGE
+.I ao-reset-lpc
+is a simple script that passes the correct arguments to openocd to
+reset the target device via a connected STlink debugging dongle.
+.SH "SEE ALSO"
+openocd(1)
+.SH AUTHOR
+Bdale Garbee
+
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.8.6)
+AC_INIT([altos], 1.8.7)
ANDROID_VERSION=17
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2018-06-17
+RELEASE_DATE=2018-10-08
AC_SUBST(RELEASE_DATE)
VERSION_DASH=`echo $VERSION | sed 's/\./-/g'`
dnl ==========================================================================
dnl Java library versions
-ALTOSUILIB_VERSION=12
-ALTOSLIB_VERSION=12
+ALTOSUILIB_VERSION=13
+ALTOSLIB_VERSION=13
AC_SUBST(ALTOSLIB_VERSION)
AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package])
AC_SUBST(FATDIR)
AC_ARG_WITH(google-key, AS_HELP_STRING([--with-google-key=PATH],
- [Set the file to read the google maps API key from (defaults to ~/altusmetrumllc/google-maps-api-key)]),
- [GOOGLEKEYFILE=$withval], [GOOGLEKEYFILE=$HOME/altusmetrumllc/google-maps-api-key])
+ [Set the file to read the AltosDroid maps API key from (defaults to ~/altusmetrumllc/google-altosdroid-maps-api-key)]),
+ [GOOGLEKEYFILE=$withval], [GOOGLEKEYFILE=$HOME/altusmetrumllc/google-altosdroid-maps-api-key])
if test -r "$GOOGLEKEYFILE" -a -s "$GOOGLEKEYFILE"; then
GOOGLEKEY=`cat "$GOOGLEKEYFILE"`
HAVE_GOOGLE_KEY="no"
fi
+AC_ARG_ENABLE(faketime, AS_HELP_STRING([--enable-faketime],
+ [Use faketime program to ensure pdf files are reproducible (default=no)]),
+ [FAKETIME=$enableval], [FAKETIME=no])
+
+AM_CONDITIONAL(FAKETIME, [test x$FAKETIME = xyes])
+
AC_SUBST(GOOGLEKEY)
AC_PROG_CC
AC_MSG_ERROR([Please install nickle to build AltOs])
fi
+PKG_CHECK_MODULES([JANSSON], [jansson])
+
AC_ARG_WITH([readline],
[AS_HELP_STRING([--with-readline],
[enable readline functionality in ao-dbg @<:@default=auto@:>@])],
Makefile
src/Makedefs
src/chaoskey-v1.0/org.altusmetrum.ChaosKey.metainfo.xml
+doc/Makefile
altoslib/Makefile
altoslib/AltosVersion.java
icon/Makefile
ao-tools/ao-chaosread/Makefile
ao-tools/ao-makebin/Makefile
ao-utils/Makefile
+map-server/Makefile
+map-server/altos-mapd/Makefile
+map-server/altos-map/Makefile
+map-server/altos-mapj/Makefile
src/Version
])
echo " jfreechart..................: ${JFREECHART}"
echo " jcommon.....................: ${JCOMMON}"
echo " JVM include.................: ${JVM_INCLUDE}"
-echo " Google maps API key.........: ${HAVE_GOOGLE_KEY}"
+echo " AltosDroid maps API key.....: ${HAVE_GOOGLE_KEY}"
if test x${ANDROID_SDK} != "xno"; then
echo ""
echo " Android path"
*.raw
titlepage.templates.xsl
fop-cfg.xml
+map-loading.svg
+++ /dev/null
-#
-# http://docbook.sourceforge.net/release/xsl/current/README
-#
-
-RELNOTES_INC=\
- release-notes-1.8.6.inc \
- release-notes-1.8.5.inc \
- release-notes-1.8.4.inc \
- release-notes-1.8.3.inc \
- release-notes-1.8.2.inc \
- release-notes-1.8.1.inc \
- release-notes-1.8.inc \
- release-notes-1.7.inc \
- release-notes-1.6.8.inc \
- release-notes-1.6.5.inc \
- release-notes-1.6.4.inc \
- release-notes-1.6.3.inc \
- release-notes-1.6.2.inc \
- release-notes-1.6.1.inc \
- release-notes-1.6.inc \
- release-notes-1.5.inc \
- release-notes-1.4.2.inc \
- release-notes-1.4.1.inc \
- release-notes-1.4.inc \
- release-notes-1.3.2.inc \
- release-notes-1.3.1.inc \
- release-notes-1.3.inc \
- release-notes-1.2.1.inc \
- release-notes-1.2.inc \
- release-notes-1.1.1.inc \
- release-notes-1.1.inc \
- release-notes-1.0.1.inc \
- release-notes-0.9.2.inc \
- release-notes-0.9.inc \
- release-notes-0.8.inc \
- release-notes-0.7.1.inc
-
-IMAGES=\
- altosui.png \
- ascent.png \
- configure-altimeter.png \
- configure-altosui.png \
- configure-groundstation.png \
- configure-pyro.png \
- descent.png \
- device-selection.png \
- easymega.svg \
- easymega-v1.0-bottom.jpg \
- easymega-v1.0-top.jpg \
- easymini.svg \
- easymini-top.jpg \
- fire-igniter.png \
- graph-configure.png \
- graph-map.png \
- graph.png \
- graph-stats.png \
- ignitor.png \
- landed.png \
- launch-pad.png \
- load-maps.png \
- micropeak-app.png \
- micropeak-back.jpg \
- micropeak-device-dialog.png \
- micropeak-dime.jpg \
- micropeak-download.png \
- micropeak-graph-configure.png \
- micropeak-graph.png \
- micropeak-nofont.svg \
- micropeak-preferences.png \
- micropeak-raw-data.png \
- micropeak-save-dialog.png \
- micropeak-statistics.png \
- MicroPeakUSB-2.0-inuse.jpg \
- MicroPeakUSB-2.0.jpg \
- monitor-idle.png \
- scan-channels.png \
- site-map.png \
- table.png \
- telegps-configure.png \
- telegps-graph-configure.png \
- telegps-graph-graph.png \
- telegps-graph-map.png \
- telegps-graph-stats.png \
- telegps-info.png \
- telegps-location.png \
- telegps-map.png \
- telegps-preferences.png \
- telegps-scan.png \
- telegps-status.png \
- telegps-table.png \
- telegps-v1.0-top.jpg \
- telemega.svg \
- telemega-v1.0-top.jpg \
- telemetrum.svg \
- telemetrum-v1.1-thside.jpg \
- telemetrum-v2.0-th.jpg \
- telemini-v1.svg \
- telemini-v1-top.jpg \
- telemini-v3.svg \
- telemini-v3.0-top.jpg \
- telemini-v3.0-bottom.jpg \
- altusmetrum-oneline.svg \
- telegps-oneline.svg \
- micropeak-oneline.svg
-
-TXT_FILES=altusmetrum.txt
-
-COMMON_INC_FILES=\
- config-device.inc \
- config-ui.inc \
- load-maps.inc \
- aprs-operation.inc \
- handling.inc
-
-INC_FILES=\
- dedication.inc \
- intro.inc \
- getting-started.inc \
- usage.inc \
- telemetrum.inc \
- telemini.inc \
- easymini-device.inc \
- telemega.inc \
- easymega.inc \
- installation.inc \
- using-am-products.inc \
- updating-firmware.inc \
- altosui.inc \
- altosdroid.inc \
- system-operation.inc \
- pyro-channels.inc \
- flight-data-recording.inc \
- specs.inc \
- $(COMMON_INC_FILES) \
- release-notes.inc \
- $(RELNOTES_INC)
-
-RAW_FILES=$(TXT_FILES:.txt=.raw) $(INC_FILES:.inc=.raw)
-
-TELEGPS_INC_FILES=\
- telegps-dedication.inc \
- telegps-quick-start.inc \
- telegps-using.inc \
- telegps-system-operation.inc \
- telegps-application.inc \
- telegps-specs.inc \
- telegps-updating-firmware.inc \
- telegps-release-notes.inc \
- $(COMMON_INC_FILES)
-
-TELEGPS_TXT_FILES=\
- telegps.txt
-
-TELEGPS_RAW_FILES=$(TELEGPS_TXT_FILES:.txt=.raw) $(TELEGPS_INC_FILES:.inc=.raw)
-
-MICROPEAK_TXT_FILES=\
- micropeak.txt
-
-MICROPEAK_INC_FILES=
-
-MICROPEAK_RAW_FILES=$(MICROPEAK_TXT_FILES:.txt=.raw) $(MICROPEAK_INC_FILES:.inc=.raw)
-
-EASYMINI_TXT_FILES=\
- easymini.txt
-
-EASYMINI_INC_FILES=$(INC_FILES) easymini-release-notes.inc
-
-
-EASYMINI_RAW_FILES=$(EASYMINI_TXT_FILES:.txt=.raw) $(EASYMINI_INC_FILES:.inc=.raw)
-
-OUTLINE_TXT_FILES=\
- easymega-outline.txt \
- easymini-outline.txt \
- telemega-outline.txt \
- telemetrum-outline.txt \
- telemini-v1-outline.txt \
- telemini-v3-outline.txt \
- telegps-outline.txt
-
-OUTLINE_RAW_FILES=$(OUTLINE_TXT_FILES:.txt=.raw)
-
-OUTLINE_PDF_FILES=$(OUTLINE_TXT_FILES:.txt=.pdf)
-
-SVG=\
- easymini.svg \
- telemega.svg \
- telemetrum.svg \
- telemini-v1.svg \
- telemini-v3.svg \
- easymega.svg
-
-RELNOTES_HTML=$(RELNOTES_INC:.inc=.html)
-
-ONEFILE_TXT_FILES=\
- altos.txt \
- companion.txt \
- telemetry.txt
-
-ONEFILE_RAW_FILES=$(ONEFILE_TXT_FILES:.txt=.raw)
-ONEFILE_PDF_FILES=$(ONEFILE_TXT_FILES:.txt=.pdf)
-ONEFILE_HTML_FILES=$(ONEFILE_TXT_FILES:.txt=.html)
-
-AM_HTML=am.html
-
-PUBLISH_HTML=altusmetrum.html micropeak.html telegps.html easymini.html $(ONEFILE_HTML_FILES)
-
-HTML=$(PUBLISH_HTML) $(RELNOTES_HTML)
-
-HTML_REVHISTORY=\
- altusmetrum-revhistory.html \
- micropeak-revhistory.html \
- telegps-revhistory.html \
- easymini-revhistory.html
-
-PDF=altusmetrum.pdf micropeak.pdf telegps.pdf easymini.pdf $(ONEFILE_PDF_FILES) \
- $(OUTLINE_PDF_FILES)
-
-FOP_STYLE=am-fo.xsl
-HTML_STYLE=am-html.xsl
-COMMON_STYLE=common.xsl
-FOP_XCONF=fop.xconf
-STYLESHEET=am.css
-
-FONTS=\
- fonts/DejaVuSansMono-BoldOblique.ttf \
- fonts/DejaVuSansMono-Bold.ttf \
- fonts/DejaVuSansMono-Oblique.ttf \
- fonts/DejaVuSansMono.ttf \
- fonts/OpenSans-Light.ttf \
- fonts/OpenSans-LightItalic.ttf \
- fonts/OpenSans-Regular.ttf \
- fonts/OpenSans-Italic.ttf \
- fonts/OpenSans-Semibold.ttf \
- fonts/OpenSans-SemiboldItalic.ttf
-
-TEMPLATES_TMPL=titlepage.templates.tmpl
-
-TEMPLATES_XSL=$(TEMPLATES_TMPL:.tmpl=.xsl)
-
-PDF_CONFIG_FILES=$(FOP_STYLE) $(COMMON_STYLE) $(FOP_XCONF) $(TEMPLATES_XSL)
-HTML_CONFIG_FILES=$(HTML_STYLE) $(COMMON_STYLE) $(TEMPLATES_XSL)
-
-PUBLISH_DOC=$(PUBLISH_HTML) $(HTML_REVHISTORY) $(PDF) $(IMAGES) $(STYLESHEET)
-
-DOC=$(HTML) $(HTML_REVHISTORY) $(PDF) $(IMAGES) $(STYLESHEET)
-
-.SUFFIXES: .tmpl .xsl .inc .txt .raw .pdf .html
-
-.txt.raw:
- sed -e 's/^[ ]*//' -e 's/^\\//' $*.txt > $@
-
-.inc.raw:
- sed -e 's/^[ ]*//' -e 's/^\\//' $*.inc > $@
-
-.raw.html:
- a2x --verbose -a docinfo -f pdf --xsltproc-opts "--stringparam toc.section.depth 2" --xsl-file $(FOP_STYLE) --fop --fop-opts="-c $(FOP_XCONF)" $*.raw
- a2x --verbose -a docinfo -f xhtml --xsltproc-opts "--stringparam toc.section.depth 2" --xsl-file $(HTML_STYLE) --stylesheet=$(STYLESHEET) $*.raw
- case $* in release-notes*) ./fix-html $*.html ;; esac
-
-.html.pdf:
- @touch $@
-
-.tmpl.xsl:
- xsltproc --output $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/template/titlepage.xsl $*.tmpl
-
-all: $(HTML) $(PDF)
-
-altusmetrum-revhistory.html: altusmetrum.html
-
-micropeak-revhistory.html: micropeak.html
-
-telegps-revhistory.html: telegps.html
-
-altusmetrum.pdf altusmetrum.html: altusmetrum-docinfo.xml $(RAW_FILES) $(IMAGES)
-
-telegps.html telegps.pdf: telegps-docinfo.xml $(TELEGPS_RAW_FILES) $(IMAGES)
-
-micropeak.pdf micropeak.html: micropeak-docinfo.xml $(MICROPEAK_RAW_FILES) $(IMAGES)
-
-easymini.pdf easymini.html: easymini-docinfo.xml $(EASYMINI_RAW_FILES) $(IMAGES)
-
-telemini-v1-outline.pdf: telemini-v1-outline.txt telemini-v1.svg
-
-telemini-v3-outline.pdf: telemini-v3-outline.txt telemini-v3.svg
-
-install: all
-
-WEB_ROOT=/home/bdale/web/
-
-publish: $(PUBLISH_DOC) $(FONTS)
- cp $(PUBLISH_DOC) $(WEB_ROOT)/altusmetrum/AltOS/doc/
- mkdir -p $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/
- cp $(FONTS) $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/
- (cd $(WEB_ROOT)/altusmetrum ; \
- git add $(WEB_ROOT)/altusmetrum/AltOS/doc/* ; \
- git add $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/* ; \
- echo "update docs" | \
- git commit -F - $(WEB_ROOT)/altusmetrum/AltOS/doc/* $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/* ; \
- git push)
-
-publish-keithp: am.html $(PUBLISH_DOC) $(FONTS)
- scp -p am.html $(PUBLISH_DOC) keithp.com:~keithp/public_html/altos
- scp -p $(FONTS) keithp.com:~keithp/public_html/altos/fonts
-
-clean:
- rm -f am.html $(HTML) $(HTML_REVHISTORY) $(PDF) $(TEMPLATES_XSL) $(RAW_FILES) $(TELEGPS_RAW_FILES) $(MICROPEAK_RAW_FILES)
-
-distclean: clean
- rm -f $(HTML) $(PDF)
-
-$(PDF): $(PDF_CONFIG_FILES)
-$(HTML): $(HTML_CONFIG_FILES)
-
-am.html: Makefile make-am-html $(HTML)
- sh ./make-am-html $(HTML) > $@
--- /dev/null
+#
+# http://docbook.sourceforge.net/release/xsl/current/README
+#
+
+if FAKETIME
+FAKETIME=TZ=UTC faketime -f '$(RELEASE_DATE) 00:00:00 i0'
+endif
+
+RELNOTES_INC=\
+ release-notes-1.8.7.inc \
+ release-notes-1.8.6.inc \
+ release-notes-1.8.5.inc \
+ release-notes-1.8.4.inc \
+ release-notes-1.8.3.inc \
+ release-notes-1.8.2.inc \
+ release-notes-1.8.1.inc \
+ release-notes-1.8.inc \
+ release-notes-1.7.inc \
+ release-notes-1.6.8.inc \
+ release-notes-1.6.5.inc \
+ release-notes-1.6.4.inc \
+ release-notes-1.6.3.inc \
+ release-notes-1.6.2.inc \
+ release-notes-1.6.1.inc \
+ release-notes-1.6.inc \
+ release-notes-1.5.inc \
+ release-notes-1.4.2.inc \
+ release-notes-1.4.1.inc \
+ release-notes-1.4.inc \
+ release-notes-1.3.2.inc \
+ release-notes-1.3.1.inc \
+ release-notes-1.3.inc \
+ release-notes-1.2.1.inc \
+ release-notes-1.2.inc \
+ release-notes-1.1.1.inc \
+ release-notes-1.1.inc \
+ release-notes-1.0.1.inc \
+ release-notes-0.9.2.inc \
+ release-notes-0.9.inc \
+ release-notes-0.8.inc \
+ release-notes-0.7.1.inc
+
+IMAGES=\
+ altosui.png \
+ ascent.png \
+ configure-altimeter.png \
+ configure-altosui.png \
+ configure-groundstation.png \
+ configure-pyro.png \
+ descent.png \
+ device-selection.png \
+ easymega.svg \
+ easymega-v1.0-bottom.jpg \
+ easymega-v1.0-top.jpg \
+ easymini.svg \
+ easymini-top.jpg \
+ fire-igniter.png \
+ graph-configure.png \
+ graph-map.png \
+ graph.png \
+ graph-stats.png \
+ ignitor.png \
+ landed.png \
+ launch-pad.png \
+ load-maps.png \
+ micropeak-app.png \
+ micropeak-back.jpg \
+ micropeak-device-dialog.png \
+ micropeak-dime.jpg \
+ micropeak-download.png \
+ micropeak-graph-configure.png \
+ micropeak-graph.png \
+ micropeak-nofont.svg \
+ micropeak-preferences.png \
+ micropeak-raw-data.png \
+ micropeak-save-dialog.png \
+ micropeak-statistics.png \
+ MicroPeakUSB-2.0-inuse.jpg \
+ MicroPeakUSB-2.0.jpg \
+ monitor-idle.png \
+ scan-channels.png \
+ site-map.png \
+ table.png \
+ telegps-configure.png \
+ telegps-graph-configure.png \
+ telegps-graph-graph.png \
+ telegps-graph-map.png \
+ telegps-graph-stats.png \
+ telegps-info.png \
+ telegps-location.png \
+ telegps-map.png \
+ telegps-preferences.png \
+ telegps-scan.png \
+ telegps-status.png \
+ telegps-table.png \
+ telegps-v1.0-top.jpg \
+ telemega.svg \
+ telemega-v1.0-top.jpg \
+ telemetrum.svg \
+ telemetrum-v1.1-thside.jpg \
+ telemetrum-v2.0-th.jpg \
+ telemini-v1.svg \
+ telemini-v1-top.jpg \
+ telemini-v3.svg \
+ telemini-v3.0-top.jpg \
+ telemini-v3.0-bottom.jpg \
+ altusmetrum-oneline.svg \
+ telegps-oneline.svg \
+ micropeak-oneline.svg
+
+TXT_FILES=altusmetrum.txt
+
+COMMON_INC_FILES=\
+ config-device.inc \
+ config-ui.inc \
+ load-maps.inc \
+ aprs-operation.inc \
+ handling.inc
+
+INC_FILES=\
+ dedication.inc \
+ intro.inc \
+ getting-started.inc \
+ usage.inc \
+ telemetrum.inc \
+ telemini.inc \
+ easymini-device.inc \
+ telemega.inc \
+ easymega.inc \
+ installation.inc \
+ using-am-products.inc \
+ updating-firmware.inc \
+ altosui.inc \
+ altosdroid.inc \
+ system-operation.inc \
+ pyro-channels.inc \
+ flight-data-recording.inc \
+ specs.inc \
+ $(COMMON_INC_FILES) \
+ release-notes.inc \
+ $(RELNOTES_INC)
+
+RAW_FILES=$(TXT_FILES:.txt=.raw) $(INC_FILES:.inc=.raw)
+
+TELEGPS_INC_FILES=\
+ telegps-dedication.inc \
+ telegps-quick-start.inc \
+ telegps-using.inc \
+ telegps-system-operation.inc \
+ telegps-application.inc \
+ telegps-specs.inc \
+ telegps-updating-firmware.inc \
+ telegps-release-notes.inc \
+ $(COMMON_INC_FILES)
+
+TELEGPS_TXT_FILES=\
+ telegps.txt
+
+TELEGPS_RAW_FILES=$(TELEGPS_TXT_FILES:.txt=.raw) $(TELEGPS_INC_FILES:.inc=.raw)
+
+MICROPEAK_TXT_FILES=\
+ micropeak.txt
+
+MICROPEAK_INC_FILES=
+
+MICROPEAK_RAW_FILES=$(MICROPEAK_TXT_FILES:.txt=.raw) $(MICROPEAK_INC_FILES:.inc=.raw)
+
+EASYMINI_TXT_FILES=\
+ easymini.txt
+
+EASYMINI_INC_FILES=$(INC_FILES) easymini-release-notes.inc
+
+
+EASYMINI_RAW_FILES=$(EASYMINI_TXT_FILES:.txt=.raw) $(EASYMINI_INC_FILES:.inc=.raw)
+
+OUTLINE_TXT_FILES=\
+ easymega-outline.txt \
+ easymini-outline.txt \
+ telemega-outline.txt \
+ telemetrum-outline.txt \
+ telemini-v1-outline.txt \
+ telemini-v3-outline.txt \
+ telegps-outline.txt
+
+OUTLINE_RAW_FILES=$(OUTLINE_TXT_FILES:.txt=.raw)
+
+OUTLINE_PDF_FILES=$(OUTLINE_TXT_FILES:.txt=.pdf)
+
+SVG=\
+ easymini.svg \
+ telemega.svg \
+ telemetrum.svg \
+ telemini-v1.svg \
+ telemini-v3.svg \
+ easymega.svg
+
+RELNOTES_HTML=$(RELNOTES_INC:.inc=.html)
+
+ONEFILE_TXT_FILES=\
+ altos.txt \
+ companion.txt \
+ telemetry.txt \
+ map-loading.txt
+
+ONEFILE_RAW_FILES=$(ONEFILE_TXT_FILES:.txt=.raw)
+ONEFILE_PDF_FILES=$(ONEFILE_TXT_FILES:.txt=.pdf)
+ONEFILE_HTML_FILES=$(ONEFILE_TXT_FILES:.txt=.html)
+
+AM_HTML=am.html
+
+PUBLISH_HTML=altusmetrum.html micropeak.html telegps.html easymini.html $(ONEFILE_HTML_FILES)
+
+HTML=$(PUBLISH_HTML) $(RELNOTES_HTML)
+
+HTML_REVHISTORY=\
+ altusmetrum-revhistory.html \
+ micropeak-revhistory.html \
+ telegps-revhistory.html \
+ easymini-revhistory.html
+
+PDF=altusmetrum.pdf micropeak.pdf telegps.pdf easymini.pdf $(ONEFILE_PDF_FILES) \
+ $(OUTLINE_PDF_FILES)
+
+MAP_DOT_FILES=map-loading.dot
+MAP_SVG_FILES=$(MAP_DOT_FILES:.dot=.svg)
+FOP_STYLE=am-fo.xsl
+HTML_STYLE=am-html.xsl
+COMMON_STYLE=common.xsl
+FOP_XCONF=fop.xconf
+STYLESHEET=am.css
+
+FONTS=\
+ fonts/DejaVuSansMono-BoldOblique.ttf \
+ fonts/DejaVuSansMono-Bold.ttf \
+ fonts/DejaVuSansMono-Oblique.ttf \
+ fonts/DejaVuSansMono.ttf \
+ fonts/OpenSans-Light.ttf \
+ fonts/OpenSans-LightItalic.ttf \
+ fonts/OpenSans-Regular.ttf \
+ fonts/OpenSans-Italic.ttf \
+ fonts/OpenSans-Semibold.ttf \
+ fonts/OpenSans-SemiboldItalic.ttf
+
+TEMPLATES_TMPL=titlepage.templates.tmpl
+
+TEMPLATES_XSL=$(TEMPLATES_TMPL:.tmpl=.xsl)
+
+PDF_CONFIG_FILES=$(FOP_STYLE) $(COMMON_STYLE) $(FOP_XCONF) $(TEMPLATES_XSL)
+HTML_CONFIG_FILES=$(HTML_STYLE) $(COMMON_STYLE) $(TEMPLATES_XSL)
+
+PUBLISH_DOC=$(PUBLISH_HTML) $(HTML_REVHISTORY) $(PDF) $(IMAGES) $(STYLESHEET)
+
+DOC=$(HTML) $(HTML_REVHISTORY) $(PDF) $(IMAGES) $(STYLESHEET)
+
+SUFFIXES = .dot .svg .tmpl .xsl .inc .txt .raw .pdf .html
+
+.dot.svg:
+ dot -Tsvg -o$@ $*.dot
+
+.txt.raw:
+ sed -e 's/^[ ]*//' -e 's/^\\//' $*.txt > $@
+
+.inc.raw:
+ sed -e 's/^[ ]*//' -e 's/^\\//' $*.inc > $@
+
+.raw.html:
+ a2x -a docinfo -f xhtml --xsltproc-opts "--stringparam toc.section.depth 2" --xsl-file $(HTML_STYLE) --stylesheet=$(STYLESHEET) $*.raw
+ case $* in release-notes*) ./fix-html $*.html ;; esac
+ $(FAKETIME) a2x -a docinfo -f pdf --xsltproc-opts "--stringparam toc.section.depth 2" --xsl-file $(FOP_STYLE) --fop --fop-opts="-c $(FOP_XCONF)" $*.raw
+
+.html.pdf:
+ echo $@
+
+.tmpl.xsl:
+ xsltproc --output $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/template/titlepage.xsl $*.tmpl
+
+all: $(HTML) $(PDF)
+
+map-loading.raw: $(MAP_SVG_FILES)
+
+altusmetrum-revhistory.html: altusmetrum.html
+
+micropeak-revhistory.html: micropeak.html
+
+telegps-revhistory.html: telegps.html
+
+altusmetrum.pdf altusmetrum.html: altusmetrum-docinfo.xml $(RAW_FILES) $(IMAGES)
+
+telegps.html telegps.pdf: telegps-docinfo.xml $(TELEGPS_RAW_FILES) $(IMAGES)
+
+micropeak.pdf micropeak.html: micropeak-docinfo.xml $(MICROPEAK_RAW_FILES) $(IMAGES)
+
+easymini.pdf easymini.html: easymini-docinfo.xml $(EASYMINI_RAW_FILES) $(IMAGES)
+
+telemini-v1-outline.pdf: telemini-v1-outline.txt telemini-v1.svg
+
+telemini-v3-outline.pdf: telemini-v3-outline.txt telemini-v3.svg
+
+install: all
+
+WEB_ROOT=/home/bdale/web/
+
+publish: $(PUBLISH_DOC) $(FONTS)
+ cp $(PUBLISH_DOC) $(WEB_ROOT)/altusmetrum/AltOS/doc/
+ mkdir -p $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/
+ cp $(FONTS) $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/
+ (cd $(WEB_ROOT)/altusmetrum ; \
+ git add $(WEB_ROOT)/altusmetrum/AltOS/doc/* ; \
+ git add $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/* ; \
+ echo "update docs" | \
+ git commit -F - $(WEB_ROOT)/altusmetrum/AltOS/doc/* $(WEB_ROOT)/altusmetrum/AltOS/doc/fonts/* ; \
+ git push)
+
+publish-keithp: am.html $(PUBLISH_DOC) $(FONTS)
+ scp -p am.html $(PUBLISH_DOC) keithp.com:~keithp/public_html/altos
+ scp -p $(FONTS) keithp.com:~keithp/public_html/altos/fonts
+
+clean:
+ rm -f am.html $(HTML) $(HTML_REVHISTORY) $(PDF) $(TEMPLATES_XSL) $(RAW_FILES) $(TELEGPS_RAW_FILES) $(MICROPEAK_RAW_FILES)
+
+distclean: clean
+ rm -f $(HTML) $(PDF)
+
+$(PDF): $(PDF_CONFIG_FILES)
+$(HTML): $(HTML_CONFIG_FILES)
+
+am.html: Makefile make-am-html $(HTML)
+ sh ./make-am-html $(HTML) > $@
Creating documentation for a new release of AltOS
+* Write release notes in release-notes-${version}.inc. Add to
+ Makefile
+
* Make sure that doc/altusmetrum-docinfo.xml has the right copyright
year, and add release to the revision history at the front (release
notes will be pulled in by release-notes.inc)
-* Write release notes in release-notes-${version}.inc. Add to
- Makefile
-
* Add references to that as appropriate from each of the
documents:
telemetry-docinfo.xml
* Add release-notes-${version}.inc to git
+
+* Make sure new hardware specs are documented in specs.inc
</legalnotice>
<revhistory>
<?dbhtml filename="altusmetrum-revhistory.html"?>
+ <revision>
+ <revnumber>1.8.7</revnumber>
+ <date>8 Oct 2018</date>
+ <revremark>
+ Include TeleMega v3.0 firmware in release. Fix TeleBT v4.0 RF
+ calibration to factory value when reflashing. Fix map images.
+ Fix Mac OS X support.
+ </revremark>
+ </revision>
<revision>
<revnumber>1.8.6</revnumber>
<date>6 Aug 2018</date>
--- /dev/null
+digraph map_loading {
+ edge [arrowsize=0.5; style="setlinewidth(2)"]
+ node [style=filled; fontcolor=white; color=invis; shape=box; arrowsize=0.5; fontname="DejaVu Sans,sans-serif"; fontsize=12; height=0.2;];
+ edge [decorate=true; fontname="DejaVu Sans,sans-serif"; fontsize=8];
+ graph [fontname="DejaVu Sans,sans-serif"; fontsize=15; ]
+ rankdir="TB";
+ ranksep=0.5;
+ nodesep=0.5;
+ color=invis;
+ fillcolor="#c0c0c0";
+ fontcolor="white";
+
+ app -> apache [label="AltOS Map URI"]
+ apache -> app [label="Google Map tile"]
+
+ apache -> cgi_script [label="AltOS Map URI"]
+ cgi_script -> cache_manager [label="AltOS Tile Request"]
+
+ cgi_script -> apache [label="Google Map tile"]
+
+ cache_manager -> cgi_script [label="AltOS Tile Reply"]
+
+ cache_manager -> disk_files [label="AltOS tile files" dir="both"]
+ cache_manager -> google_maps [label="Google Map URI"]
+
+ google_maps -> cache_manager [label="Google Map tile"]
+
+ app [color="#885931" label="Application"]
+ apache [color="#d12127" label="Apache Web Server"]
+ cgi_script [color="#551a8b" label="AltOS Map CGI Script"]
+ cache_manager [color="#c75b1c" label="AltOS Map Cache Manager"]
+ disk_files [color="#4f81bd" label="File System"]
+ google_maps [color="#4cbb44" label="Google Maps"]
+}
+
--- /dev/null
+= Loading Map Tiles from Google Maps
+:doctype: article
+
+== The Google Maps Problem
+
+Until recently, Google Maps could be used without fee to fetch map
+tiles. Applications could load map tiles anonymously or using a key;
+when used anonymously, the number of tiles that could be loaded per
+day and the rate at which tiles could be loaded was throttled to make
+the API practical only for development purpose. With an application
+key, the number of tiles available per day was much higher, and there
+was no rate limiting. This was usually sufficient for Altos Metrum
+customer use.
+
+However, this has changed and now there is no way to load map tiles
+anonymously, and any application key must be tied to a credit
+card. The tile cap for free usage is now monthly instead of
+daily. Because the key is tied to a credit card, we should not ship it
+with the application any longer. And because the cap is monthly
+instead of daily, we need some way to control usage by our
+applications.
+
+=== The Proposed Solution — An Intermediate Service
+
+To give us some measure of control over tile loading, we will want to
+interpose a server controlled by us between the application and Google
+Maps. This will let us store the Google Maps key in a secure location,
+and also control tile loading by each user.
+
+image::map-loading.svg[align="center"]
+
+== AltOS Map Service
+
+This service receives a URL request and replies with either a map tile
+or an error. It is functionally equivalent to the Google Maps service,
+except that it can control use of the Google Maps API.
+
+=== AltOS Map CGI Script
+
+The AltOS Map CGI Script is a straightforward script which connects to
+the AltOS Map Cache Manager, transmits a URL describing the desired
+map tile and receives back a filename (or error), then sends the
+contents of that file back through Apache to the requesting
+application. The name of the script is 'altos-map'.
+
+==== Inputs
+
+The AltOS Map CGI Script will parse the provided AltOS Map URI or
+AltOS Version URI.
+
+==== Outputs
+
+For AltOS Map URLs, the CGI Script will return either the contents of
+the associated Google Map tile or an error indicating what failed:
+
+_200 OK_: The map tile image data or version information
+
+_400 Bad Request_: The URL is malformed or not compatible with the
+version supported by the service
+
+_403 Forbidden_: The map tile is outside the areas supported by the
+current AltOS Map service area
+
+_408 Request Timeout_: Attempts to fetch the tile from Google Maps
+timed out.
+
+_503 Service Unavailable_: The service is temporarily refusing to
+satisfy this request due to resource limitations.
+
+=== AltOS Map Cache Manager
+
+This is a service running on the local machine and available over a
+local network socket. It translates an AltOS Map URL into a local
+filename containing the contents of the associated Google Maps
+tile. The name of the cache manager is 'altos-mapd'. It will listen
+for requests on port 16717.
+
+=== AltOS Map URI
+
+AltOS uses a limited subset of the Google Maps, and the AltOS Map URIs
+only encode those elements which we currently use. This specification
+describes AltOS Map URI format version 1.0.0. The application is
+required to provide URIs compatible with the format supported by the
+server. The elements of the elements are:
+
+ * Latitude of center point
+ * Longitude of center point
+ * Zoom level (from bushes to planets)
+
+Encoding this in a URI is straightforward:
+
+\ altos-map?lat=<lat>&lon=<lon>&zoom=<zoom>
+
+Latitude and longitude are both encoded using decimal degrees with 6
+digits following the decimal point.
+
+Zoom levels can range from 1 (world) to 20 (buildings). Higher zoom
+levels show smaller areas at greater detail.
+
+The only Google Map type supported by version 1.0.0 of the service is
+“hybrid”, which combines road graphics on top of satellite images.
+
+Version 1.0.0 always returns images which are 512x512 pixels.
+
+If we need additional elements in the URL, we can add them in the
+future and bump the supported version number.
+
+=== AltOS Version URI
+
+To allow applications to discover what AltOS Map URI version is supported by the
+AltOS Map service, the application may query the version of the API
+supported using the Version URI. The application provides the version
+that it supports and the AltOS Map service returns a version not
+greater than the client version:
+
+\ altos-map?version=<client-major>.<client-minor>.<client-revision>
+\ →
+\ <server-major>.<server-minor>.<server.revision>
+
+=== AltOS Tile Request
+
+The AltOS Map CGI Script parses the Map URI and passes that
+information to the AltOS Map Cache Manager using the AltOS Tile
+Specifier syntax. This is a JSON representation of the same data
+provided by the URI:
+
+\ {
+\ "lat": <latitude>,
+\ "lon": <longitude>,
+\ "zoom": <zoom-level>,
+\ "remote_addr": "<IPv4 or IPv6 address of requesting client>"
+\ }
+
+Latitude and longitude are both encoded using decimal degrees with 6
+digits following the decimal point.
+
+=== AltOS Tile Reply
+
+Sent back from the Cache Manager to the CGI Script, this encodes the
+status of the request and the filename of any tile data available. It
+is encoded in JSON format:
+
+\ {
+\ "status": <HTTP status>,
+\ "filename": "<absolute path to image file>",
+\ "content_type": "<HTTP content-type>"
+\ }
+
+The “filename” and “content-type” elements are only included when
+the status is _200 OK_.
+
+=== AltOS Tile Filename
+
+While the current AltOS Map URI version only supports a limited subset
+of the Google Maps functionality, we'll encode more of that data in
+filenames to allow for easy expansion of functionality in the
+future. The elements of an AltOS Tile filename consist of :
+
+ * Latitude, with N/S indicator (instead of a sign)
+ * Longitude, with E/W indicator (instead of a sign)
+ * Map type.
+ * Zoom level
+ * Scale factor. Scale, and the preceding hyphen are omitted for a scale factor of 1.
+ * Image format suffix. '.jpg' for JPEG files and '.png' for PNG files.
+
+Latitude and longitude are both encoded using decimal degrees with 6
+digits following the decimal point.
+
+Map type is one of :
+
+ _hybrid_: Road graphics over satellite images
+ _roadmap_: Symbolic road map
+ _satellite_: Un-annotated satellite images
+ _terrain_: Topographic map
+
+Here's what map filenames look like:
+
+\ map-{N,S}<lat>,{E,W}<lon>-<type>-<zoom>[-<scale>].<format>
+\
+\ map-N36.508532,W107.823944-hybrid-18.jpg
+
+To transmit this name from the AltOS Map Cache Manager back to the
+Altos Map CGI script, the filename will be wrapped in a JSON string
+
+== Implementation
+
+The AltOS Map CGI Script and AltOS Map Cache Manager will both be
+implemented in Java as much of the required Google Maps infrastructure
+is already available in that language.
+
+=== Access Control
+
+No access control to the service is planned at this point. If
+necessary, we could implement username/password access control for each
+user of the service.
+
+=== Location Restrictions
+
+To avoid unbounded usage, and confine the utility of this service to
+AltOS users, the service will only offer map tiles whose center
+location is within 10 miles of one of the sites registered in
+our launch sites database.
+
+To allow testing of the registered launch site database, a database of
+privileged clients will be supported. Privileged clients will have
+unlimited access to the service.
+
+=== Per-Client Restrictions
+
+We should implement a per-day limit on the number of tiles provided to
+a particular requesting client. We can also rate limit clients to a
+certain number of tiles per minute to reduce the bandwidth consumed
+out of our server.
+
+=== Cache Lifetime Restrictions.
+
+The Google Maps API allows for caching of map data for no more than 30
+days. To honor this, the Cache Manager will re-fetch any requested
+tiles when the cached version is older than this. If the fetch fails,
+the cache manager will continue to serve the data from the cached
+version of the file.
<email>keithp@keithp.com</email>
</author>
<copyright>
- <year>2014</year>
+ <year>2018</year>
<holder>Keith Packard</holder>
</copyright>
<mediaobject>
</legalnotice>
<revhistory>
<?dbhtml filename="micropeak-revhistory.html"?>
+ <revision>
+ <revnumber>1.8.7</revnumber>
+ <date>8 October 2018</date>
+ <revremark>
+ Poll for MicroPeak USB while the device dialog is open. Fix Mac OS X support.
+ </revremark>
+ </revision>
+ <revision>
+ <revnumber>1.8.6</revnumber>
+ <date>6 August 2018</date>
+ <revremark>
+ Report altimeter-recorded maximum height value
+ </revremark>
+ </revision>
<revision>
<revnumber>1.3.2</revnumber>
<date>12 February 2014</date>
--- /dev/null
+= Release Notes for Version 1.8.7
+:toc!:
+:doctype: article
+
+ Version 1.8.7
+
+ == AltOS
+
+ * Include TeleMega v3.0 firmware
+
+ == AltosUI, TeleGPS, MicroPeak
+
+ * Poll for new devices while Device dialog is displayed
+
+ * Wait for device to re-appear when flashing new firmware
+
+ * Fetch correct TeleBT v4.0 RF calibration values from web
+ site when reflashing.
+
+ * Change gyro headings in .csv files from x/y/z to
+ roll/pitch/yaw
+
+ * Add documentation about Packet Link mode
+
+ * Add documentation about forcing TeleMini RF parameters to
+ known values.
+
+ * Create a proxy server for Google Maps to re-enable map
+ images
+
+ * Fix Java version info in all distributed jar files so that
+ applications will run with standard Mac OS X Java.
+
+ * Replace JavaApplicationStub for Mac OS X so that
+ applications will run with Oracle Java.
+
+
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.8.7.raw[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.8.6.raw[]
|1MB
|-
|3.7-12V
+
+ |EasyMini v2.0
+ |MS5607 30km (100k')
+ |-
+ |-
+ |-
+ |1MB
+ |-
+ |3.7-12V
endif::easymini[]
ifdef::telemega[]
|8MB
|40mW
|3.7V
+
+ |TeleMega v3.0
+ |MS5607 30km (100k')
+ |MMA6555 102g
+ |uBlox Max-7Q
+ |MPU9250
+ |8MB
+ |40mW
+ |3.7V
endif::telemega[]
ifdef::easymega[]
<email>keithp@keithp.com</email>
</author>
<copyright>
- <year>2015</year>
+ <year>2018</year>
<holder>Bdale Garbee and Keith Packard</holder>
</copyright>
<mediaobject>
</legalnotice>
<revhistory>
<?dbhtml filename="telegps-revhistory.html"?>
+ <revision>
+ <revnumber>1.8.7</revnumber>
+ <date>08 Oct 2018</date>
+ <revremark>
+ Fix TeleBT v4.0 RF calibration to factory value when
+ reflashing. Fix map images. Fix Mac OS X support.
+ </revremark>
+ </revision>
<revision>
<revnumber>1.8.3</revnumber>
<date>11 Dec 2017</date>
the left power switch wire. Hook a lead to either of the
mounting holes for a ground connection.
+ === Using Packet Link Mode with TeleMini
+
+ After TeleMini powers up, it will check to see if some
+ device is attempting to communicate with it using
+ Packet Link Mode. If so, it will switch to idle mode
+ and start communicating. To switch to flight mode,
+ reboot the device either over the radio link or by
+ powering it off and back on.
+
+ If no ground station is attempting to communicate
+ using Packet Link Mode, TeleMini will enter pad mode
+ and prepare for flight.
+
+ The sequence of operations to use Packet Link Mode
+ with TeleMini is:
+
+ 1. Configure the ground station data rate, frequency
+ and callsign to match the TeleMini settings.
+
+ 2. Start Packet Link Mode in the ground station by
+ selecting the desired operation (Safe Flight Data,
+ Configure Altimeter, Fire Igniter or Monitor
+ Idle). Select the TeleBT or TeleDongle device. The
+ red LED should begin flashing rapidly.
+
+ 3. Turn on TeleMini. You should see the red LED flash
+ very rapidly during the initial communication burst,
+ but it should then slow down when the link is idle.
+
+ Once TeleMini is in Idle mode, it will stay in that
+ mode until rebooted. That means you can stop one
+ Packet Link operation, wait a while and start another
+ Packet Link operation.
+
+ === Forcing TeleMini radio parameters to known defaults
+
+ If you don't know what the TeleMini frequency and
+ callsign settings are, you can temporarily force it
+ back to the original default values (frequency
+ 434.550MHz, callsign N0CALL) by connecting a wire
+ between hole 3 and hole 7 on the debug connector. Hole
+ 3 has the square pad around it, hole 7 is the one
+ nearest the MS5607 baro sensor, which is a rectangular
+ component with a metal cap that has two holes in it.
+
+ Once TeleMini has been powered up with this wire
+ connected, the wire may be removed. The radio
+ parameters will stay set to these default values until
+ changed by the user or when the device is rebooted.
+
=== TeleMini v1
TeleMini v1 is the earlier version of this product. It
different kind of battery to any of these will destroy
the board.
endif::telemega,easymega,telemetrum[]
+
+ === Using Packet Link Mode
+
+ All AltusMetrum flight computers that have a radio can
+ communicate with the ground station software for
+ configuration and other operations using the Packet
+ Link mode. This uses radio communication instead of a
+ USB cable. To set this up, the ground station software
+ must be configured to the correct data rate, frequency
+ and callsign.
+
+ You can monitor Packet Link mode from TeleBT or
+ TeleDongle by watching the LEDs. Each time the device
+ transmits, the red LED will flash. When the link is
+ busy, or when the link is not working, the device will
+ transmit 10 times per second, so the LED will flash
+ rapidly. When the link is working and there is no data
+ to send, the link will flash once per second, and the
+ LED will flash more slowly.
--- /dev/null
+SUBDIRS=altos-mapd altos-map altos-mapj
--- /dev/null
+bin_PROGRAMS = altos-map
+
+altos_map_SOURCES = altos-map.c
+
+altos_map_LDADD = $(JANSSON_LIBS)
+altos_map_CFLAGS = $(JANSSON_CFLAGS) $(WARN_CFLAGS)
--- /dev/null
+#!/bin/sh
+# map-N43.799102,W120.586281-hybrid-20.jpg
+export QUERY_STRING="lat=43.799102&lon=-120.586281&zoom=20"
+export REMOTE_ADDR="127.0.0.1"
+./altos-map
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <jansson.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/ip.h>
+
+#define ALTOS_MAP_PORT 16717
+
+#define MISSING 0x7fffffff
+
+#define ALTOS_MAP_PROTOCOL_VERSION "1.0.0"
+
+static char *
+reason_string(int code)
+{
+ switch (code) {
+ case 200:
+ return "OK";
+ case 400:
+ return "Bad Request";
+ case 403:
+ return "Forbidden";
+ case 404:
+ return "Not Found";
+ case 408:
+ return "Request Timeout";
+ default:
+ return "Failure";
+ }
+}
+
+static void
+write_status(int status)
+{
+ printf("Status: %d %s\n", status, reason_string(status));
+}
+
+static void
+write_type(char * type)
+{
+ printf("Content-Type: %s\n", type);
+}
+
+static void
+fail(int status, char *format, ...)
+{
+ va_list ap;
+
+ write_status(status);
+ write_type("text/html");
+ printf("\n");
+ printf("<html>\n");
+ printf("<head><title>Map Fetch Failure</title></head>\n");
+ printf("<body>\n");
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+ printf("</body>\n");
+ printf("</html>\n");
+ exit(1);
+}
+
+static char *
+getenv_copy(const char *name)
+{
+ const char *value = getenv(name);
+
+ if (!value)
+ return NULL;
+
+ return strdup(value);
+}
+
+static double
+parse_double(char *string)
+{
+ char *end;
+ double value;
+
+ value = strtod(string, &end);
+ if (*end)
+ fail(400, "Invalid double %s", string);
+ return value;
+}
+
+static int
+parse_int(char *string)
+{
+ char *end;
+ long int value;
+
+ value = strtol(string, &end, 10);
+ if (*end)
+ fail(400, "Invalid int %s", string);
+ if (value < INT_MIN || INT_MAX < value)
+ fail(400, "Int value out of range %ld", value);
+ return (int) value;
+}
+
+
+static int
+connect_service(void)
+{
+ struct sockaddr_in altos_map_addr = {
+ .sin_family = AF_INET,
+ .sin_port = htons(ALTOS_MAP_PORT),
+ .sin_addr = {
+ .s_addr = htonl(INADDR_LOOPBACK),
+ },
+ };
+
+ int s = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (s < 0)
+ return -1;
+
+ if (connect (s, (const struct sockaddr *) &altos_map_addr, sizeof (altos_map_addr)) < 0) {
+ close (s);
+ return -1;
+ }
+
+ return s;
+}
+
+int main(int argc, char **argv)
+{
+
+ char *query_string = getenv_copy("QUERY_STRING");
+
+ if (query_string == NULL)
+ fail(400, "%s", "Missing query string");
+
+ char *remote_addr = getenv_copy("REMOTE_ADDR");
+
+ if (remote_addr == NULL)
+ fail(400, "%s", "Missing remote address");
+
+ double lon = MISSING;
+ double lat = MISSING;
+ int zoom = MISSING;
+ char *version = NULL;
+
+ char *query, *query_save = NULL;
+ char *query_start = query_string;
+
+ while ((query = strtok_r(query_start, "&", &query_save)) != NULL) {
+ query_start = NULL;
+
+ char *token, *token_save = NULL;
+ char *token_start = query;
+
+ char *name = NULL;
+ char *value = NULL;
+
+ while ((token = strtok_r(token_start, "=", &token_save)) != NULL) {
+ token_start = NULL;
+ if (name == NULL)
+ name = token;
+ else if (value == NULL)
+ value = token;
+ else
+ break;
+ }
+
+ if (name && value) {
+ if (!strcmp(name, "lon"))
+ lon = parse_double(value);
+ else if (!strcmp(name, "lat"))
+ lat = parse_double(value);
+ else if (!strcmp(name, "zoom"))
+ zoom = parse_int(value);
+ else if (!strcmp(name, "version"))
+ version = value;
+ else
+ fail(400, "Extra query param \"%s\"", query);
+ }
+ }
+
+ if (version != NULL) {
+ printf("Content-Type: text/plain\n");
+ printf("\n");
+ printf("%s\n", ALTOS_MAP_PROTOCOL_VERSION);
+ return 0;
+ }
+ if (lon == MISSING)
+ fail(400, "Missing longitude");
+ if (lat == MISSING)
+ fail(400, "Missing latitude");
+ if (zoom == MISSING)
+ fail(400, "Missing zoom");
+
+ int s = -1;
+ int tries = 0;
+
+ while (tries < 10 && s < 0) {
+ s = connect_service();
+ if (s < 0) {
+ usleep(100 * 1000);
+ tries++;
+ }
+ }
+
+ if (s < 0)
+ fail(408, "Cannot connect AltOS map daemon");
+
+ FILE *sf = fdopen(s, "r+");
+
+ if (sf == NULL)
+ fail(400, "allocation failure");
+
+ json_t *request = json_pack("{s:f s:f s:i s:s}", "lat", lat, "lon", lon, "zoom", zoom, "remote_addr", remote_addr);
+
+ if (request == NULL)
+ fail(400, "Cannot create JSON request");
+
+ if (json_dumpf(request, sf, 0) < 0)
+ fail(400, "Cannot write JSON request");
+
+ fflush(sf);
+
+ json_error_t error;
+ json_t *reply = json_loadf(sf, 0, &error);
+
+ if (!reply)
+ fail(400, "Cannot read JSON reply");
+
+ int status;
+
+ if (json_unpack(reply, "{s:i}", "status", &status) < 0)
+ fail(400, "No status returned");
+
+ if (status != 200)
+ fail(status, "Bad cache status");
+
+ char *filename, *content_type;
+
+ if (json_unpack(reply, "{s:s s:s}", "filename", &filename, "content_type", &content_type) < 0)
+ fail(400, "JSON reply parse failure");
+
+ int fd = open(filename, O_RDONLY);
+
+ if (fd < 0)
+ fail(400, "%s: %s", filename, strerror(errno));
+
+ struct stat statb;
+
+ if (fstat(fd, &statb) < 0)
+ fail(400, "%s: %s", filename, strerror(errno));
+
+ printf("Content-Type: %s\n", content_type);
+ printf("Content-Length: %lu\n", (unsigned long) statb.st_size);
+ printf("\n");
+ fflush(stdout);
+
+ char buf[4096];
+ ssize_t bytes_read;
+
+ while ((bytes_read = read(fd, buf, sizeof (buf))) > 0) {
+ ssize_t total_write = 0;
+ while (total_write < bytes_read) {
+ ssize_t bytes_write = write(1, buf + total_write, bytes_read - total_write);
+ if (bytes_write <= 0)
+ return 1;
+ total_write += bytes_write;
+ }
+ }
+ if (bytes_read < 0)
+ return 1;
+ return 0;
+}
--- /dev/null
+*.stamp
+*.jar
+altos-mapd
+altos-mapd-jdb
+altos-mapd-test
+classes
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package altosmapd;
+
+import java.net.*;
+import java.io.*;
+import java.text.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import org.altusmetrum.altoslib_13.*;
+
+public class AltosMapd implements AltosLaunchSiteListener {
+
+ public static int port = 16717;
+
+ public final static int maptype = AltosMap.maptype_hybrid;
+
+ public final static int px_size = 512;
+
+ public final static int scale = 1;
+
+ public static int max_zoom = 17;
+
+ public static double valid_radius = 17000; /* 17km */
+
+ public String map_dir = null;
+ public String launch_sites_file = null;
+ public String key_file = null;
+
+ public void usage() {
+ System.out.printf("usage: altos-mapd [--mapdir <map-directory] [--launch-sites <launch-sites-file>]\n" +
+ " [--radius <valid-radius-m> [--port <port>] [--key <key-file>]\n" +
+ " [--max-zoom <max-zoom-level>\n");
+ System.exit(1);
+ }
+
+ private static Semaphore launch_sites_ready;
+
+ private static List<AltosLaunchSite> launch_sites;
+
+ public void notify_launch_sites(List<AltosLaunchSite> sites) {
+ synchronized (launch_sites_ready) {
+ if (sites != null) {
+ launch_sites = sites;
+ launch_sites_ready.release();
+ }
+ }
+ }
+
+ private static boolean west_of(double a, double b) {
+ double diff = b - a;
+
+ while (diff >= 360.0)
+ diff -= 360.0;
+ while (diff <= -360.0)
+ diff += 360.0;
+
+ return diff >= 0;
+ }
+
+ public static boolean check_lat_lon(double lat, double lon, int zoom) {
+
+ if (zoom > max_zoom)
+ return false;
+
+ AltosMapTransform transform = new AltosMapTransform(px_size, px_size, zoom, new AltosLatLon(lat, lon));
+
+ AltosLatLon upper_left = transform.screen_lat_lon(new AltosPointInt(0, 0));
+ AltosLatLon lower_right = transform.screen_lat_lon(new AltosPointInt(px_size, px_size));
+
+ synchronized (launch_sites_ready) {
+ if (launch_sites == null) {
+ try {
+ launch_sites_ready.acquire();
+ } catch (InterruptedException ie) {
+ return false;
+ }
+ }
+ }
+ if (launch_sites == null) {
+ System.out.printf("No launch site data available, refusing all requests\n");
+ return false;
+ }
+
+ for (AltosLaunchSite site : launch_sites) {
+
+ /* Figure out which point in the tile to
+ * measure to the site That's one of the edges
+ * or the site location depend on where the
+ * site is in relation to the tile
+ */
+
+ double check_lon;
+
+ if (west_of(site.longitude, upper_left.lon))
+ check_lon = upper_left.lon;
+ else if (west_of(lower_right.lon, site.longitude))
+ check_lon = lower_right.lon;
+ else
+ check_lon = site.longitude;
+
+ double check_lat;
+
+ if (site.latitude < lower_right.lat)
+ check_lat = lower_right.lat;
+ else if (upper_left.lat < site.latitude)
+ check_lat = upper_left.lat;
+ else
+ check_lat = site.latitude;
+
+ AltosGreatCircle gc = new AltosGreatCircle(site.latitude, site.longitude,
+ check_lat, check_lon);
+
+ if (gc.distance <= valid_radius)
+ return true;
+ }
+
+ return false;
+ }
+
+ AltosMapdServer server;
+
+ public void process(String[] args) {
+
+ AltosPreferences.init(new AltosMapdPreferences());
+
+ int skip = 1;
+ for (int i = 0; i < args.length; i += skip) {
+ skip = 1;
+ if (args[i].equals("--mapdir") && i < args.length-1) {
+ map_dir = args[i+1];
+ skip = 2;
+ } else if (args[i].equals("--launch-sites") && i < args.length-1) {
+ launch_sites_file = args[i+1];
+ skip = 2;
+ } else if (args[i].equals("--radius") && i < args.length-1) {
+ try {
+ valid_radius = AltosParse.parse_double_locale(args[i+1]);
+ } catch (ParseException pe) {
+ usage();
+ }
+ skip = 2;
+ } else if (args[i].equals("--port") && i < args.length-1) {
+ try {
+ port = AltosParse.parse_int(args[i+1]);
+ } catch (ParseException pe) {
+ usage();
+ }
+ skip = 2;
+ } else if (args[i].equals("--key") && i < args.length-1) {
+ key_file = args[i+1];
+ skip = 2;
+ } else if (args[i].equals("--max-zoom") && i < args.length-1) {
+ try {
+ max_zoom = AltosParse.parse_int(args[i+1]);
+ } catch (ParseException pe) {
+ usage();
+ }
+ skip = 2;
+ } else {
+ usage();
+ }
+ }
+
+ if (map_dir == null)
+ usage();
+
+ if (key_file != null) {
+ try {
+ BufferedReader key_reader = new BufferedReader(new FileReader(key_file));
+
+ String line = key_reader.readLine();
+ if (line == null || line.length() != 39) {
+ System.out.printf("%s: invalid contents %d \"%s\"\n",
+ key_file, line.length(), line);
+ usage();
+ }
+ key_reader.close();
+ AltosMapStore.google_maps_api_key = line;
+ } catch (Exception e) {
+ System.out.printf("%s: %s\n", key_file, e.toString());
+ usage();
+ }
+ }
+
+ AltosPreferences.mapdir = new File(map_dir);
+
+ if (launch_sites_file != null)
+ AltosLaunchSites.launch_sites_url = "file://" + launch_sites_file;
+
+ launch_sites_ready = new Semaphore(0);
+
+ new AltosLaunchSites(this);
+
+ try {
+ server = new AltosMapdServer(port);
+ } catch (IOException ie) {
+ System.out.printf("Cannot bind to port %d: %s\n", port, ie.toString());
+ usage();
+ }
+
+ for (;;) {
+ try {
+ Socket client = server.accept();
+ if (client == null) {
+ System.out.printf("accept failed\n");
+ continue;
+ }
+ new AltosMapdClient(client);
+ } catch (Exception e) {
+ System.out.printf("Exception %s\n", e.toString());
+ }
+ }
+ }
+
+ public void AltosMapd() {
+ }
+
+ public static void main(final String[] args) {
+ new AltosMapd().process(args);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package altosmapd;
+
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+import org.altusmetrum.altoslib_13.*;
+
+public class AltosMapdClient extends Thread implements AltosMapStoreListener {
+ private Socket socket;
+ private AltosJson request;
+ private AltosJson reply;
+
+ private int http_status;
+
+ private void set_status(int status) {
+ http_status = status;
+ reply.put("status", status);
+ }
+
+ private void set_filename(String filename) {
+ reply.put("filename", filename);
+
+ }
+
+ private void set_content_type(String content_type) {
+ reply.put("content_type", content_type);
+ }
+
+ private String content_type(File file) {
+ String content_type = "application/octet-stream";
+ String basename = file.getName();
+ if (basename.endsWith(".jpg"))
+ content_type = "image/jpeg";
+ if (basename.endsWith(".png"))
+ content_type = "image/png";
+ return content_type;
+ }
+
+ private void set_file(File file) {
+ set_filename(file.getAbsolutePath());
+ set_content_type(content_type(file));
+ }
+
+ private Semaphore store_ready;
+
+ public void notify_store(AltosMapStore map_store, int status) {
+ if (status != AltosMapTile.fetching)
+ store_ready.release();
+ }
+
+ public void run() {
+ reply = new AltosJson();
+ try {
+ request = AltosJson.fromInputStream(socket.getInputStream());
+
+ if (request == null) {
+ set_status(400);
+ System.out.printf("client failed %d\n", http_status);
+ } else {
+
+ double lat = request.get_double("lat", AltosLib.MISSING);
+ double lon = request.get_double("lon", AltosLib.MISSING);
+ int zoom = request.get_int("zoom", AltosLib.MISSING);
+ String addr = request.get_string("remote_addr", null);
+
+ if (lat == AltosLib.MISSING ||
+ lon == AltosLib.MISSING ||
+ zoom == AltosLib.MISSING ||
+ addr == null)
+ {
+ set_status(400);
+ } else if (!AltosMapd.check_lat_lon(lat, lon, zoom)) {
+ set_status(403); /* Forbidden */
+ } else {
+
+ store_ready = new Semaphore(0);
+
+ AltosMapStore map_store = AltosMapStore.get(new AltosLatLon(lat, lon),
+ zoom,
+ AltosMapd.maptype,
+ AltosMapd.px_size,
+ AltosMapd.scale);
+ int status;
+
+ if (map_store == null) {
+ status = AltosMapTile.failed;
+ } else {
+ map_store.add_listener(this);
+
+ try {
+ store_ready.acquire();
+ } catch (Exception ie) {
+ }
+
+ status = map_store.status();
+ }
+
+ if (status == AltosMapTile.fetched || status == AltosMapTile.loaded) {
+ set_status(200);
+ set_file(map_store.file);
+ } else if (status == AltosMapTile.failed) {
+ set_status(404);
+ } else if (status == AltosMapTile.fetching) {
+ set_status(408);
+ } else if (status == AltosMapTile.bad_request) {
+ set_status(400);
+ } else if (status == AltosMapTile.forbidden) {
+ set_status(403);
+ } else {
+ set_status(400);
+ }
+ }
+ System.out.printf("%s: %.6f %.6f %d status %d\n",
+ addr, lat, lon, zoom, http_status);
+ }
+ } catch (Exception e) {
+ System.out.printf("client exception %s\n", e.toString());
+ e.printStackTrace(System.out);
+ set_status(400);
+
+ } finally {
+ try {
+ Writer writer = new PrintWriter(socket.getOutputStream());
+ reply.write(writer);
+ writer.write('\n');
+ writer.flush();
+ } catch (IOException ie) {
+ }
+ try {
+ socket.close();
+ } catch (IOException ie) {
+ }
+ }
+ }
+
+ public AltosMapdClient(Socket socket) {
+ this.socket = socket;
+ start();
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package altosmapd;
+
+import java.io.*;
+
+import org.altusmetrum.altoslib_13.*;
+
+public class AltosMapdPreferences extends AltosPreferencesBackend {
+
+ public String getString(String key, String def) {
+ return def;
+ }
+ public void putString(String key, String value) {
+ }
+
+ public int getInt(String key, int def) {
+ return def;
+ }
+
+ public void putInt(String key, int value) {
+ }
+
+ public double getDouble(String key, double def) {
+ return def;
+ }
+
+ public void putDouble(String key, double value) {
+ }
+
+ public boolean getBoolean(String key, boolean def) {
+ return def;
+ }
+
+ public void putBoolean(String key, boolean value) {
+ }
+
+ public byte[] getBytes(String key, byte[] def) {
+ return def;
+ }
+
+ public void putBytes(String key, byte[] value) {
+ }
+
+ public boolean nodeExists(String key) {
+ return false;
+ }
+
+ public AltosPreferencesBackend node(String key) {
+ return this;
+ }
+
+ public String[] keys() {
+ return null;
+ }
+
+ public void remove(String key) {
+ }
+
+ public void flush() {
+ }
+
+ public File homeDirectory() {
+ return new File (".");
+ }
+
+ public void debug(String format, Object ... arguments) {
+ System.out.printf(format, arguments);
+ }
+
+ public AltosMapdPreferences() {
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package altosmapd;
+
+import java.net.*;
+import java.io.*;
+
+public class AltosMapdServer extends ServerSocket {
+ public AltosMapdServer(int port) throws IOException {
+ super(port, 256, InetAddress.getLoopbackAddress());
+ }
+}
--- /dev/null
+JAVAROOT=classes
+AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6
+
+altoslibdir=$(libdir)/altos
+
+CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="$(JAVAROOT):../../altoslib/*"
+
+bin_SCRIPTS=altos-mapd
+
+altosmapd_JAVA = \
+ AltosMapd.java \
+ AltosMapdServer.java \
+ AltosMapdClient.java \
+ AltosMapdPreferences.java
+
+ALTOSLIB_CLASS=\
+ altoslib_$(ALTOSLIB_VERSION).jar
+
+JAR=altosmapd.jar
+
+FATJAR=altosmapd-fat.jar
+
+all-local: classes/altosmapd $(JAR) altos-mapd altos-mapd-test altos-mapd-jdb
+
+defaultsdir=$(sysconfdir)/default
+
+defaults_DATA=altos-mapd-default
+
+systemddir=$(libdir)/systemd/system
+
+systemd_DATA=altos-mapd.service
+
+install-altosmapdJAVA: altosmapd.jar
+ @$(NORMAL_INSTALL)
+ test -z "$(altosmapddir)" || $(MKDIR_P) "$(DESTDIR)$(altosmapddir)"
+ echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(altosmapddir)/altosdmap.jar'"; \
+ $(INSTALL_DATA) "$<" "$(DESTDIR)$(altosmapddir)"
+
+classes/altosmapd:
+ mkdir -p classes/altosmapd
+
+$(JAR): classaltosmapd.stamp Manifest.txt $(ALTOSLIB_CLASS)
+ jar cfm $@ Manifest.txt \
+ -C classes altosmapd
+
+altosmapddir=$(datadir)/java
+
+$(FATJAR): classaltosmapd.stamp Manifest-fat.txt $(ALTOSLIB_CLASS)
+ jar cfm $@ Manifest-fat.txt \
+ -C classes altosmapd
+
+altos-mapd: Makefile
+ echo "#!/bin/sh" > $@
+ echo 'exec java -Djava.library.path="$(altoslibdir)" -jar "$(altosmapddir)/altosmapd.jar" "$$@"' >> $@
+ chmod +x $@
+
+altos-mapd-test: Makefile
+ echo '#!/bin/sh' > $@
+ echo 'dir="$$(dirname $$0)"' >> $@
+ echo 'cd "$$dir"' >> $@
+ echo 'altosmapd="$$(pwd -P)"' >> $@
+ echo 'exec java -jar "$$altosmapd/altosmapd.jar" "$$@"' >> $@
+ chmod +x $@
+
+altos-mapd-jdb: Makefile
+ echo "#!/bin/sh" > $@
+ echo 'exec jdb altosmapd/AltosMapd "$$@"' >> $@
+ chmod +x $@
+
+$(ALTOSLIB_CLASS):
+ -rm -f "$@"
+ $(LN_S) ../../altoslib/"$@" .
+
--- /dev/null
+Main-Class: altosmapd.AltosMapd
+Class-Path: altoslib_13.jar
--- /dev/null
+MAPKEY=/home/altos-mapd/google-maps-api-key
+MAPDIR=/home/altos-mapd/maps
+LAUNCHSITES=/var/www/html/launch-sites.txt
+MAXZOOM=17
--- /dev/null
+[Unit]
+Description=AltOS Map Cache
+Requires=network-online.target
+After=network-online.target
+
+[Service]
+Type=simple
+User=altos-mapd
+Restart=always
+EnvironmentFile=/etc/default/altos-mapd-default
+ExecStart=/usr/bin/altos-mapd --key $MAPKEY --mapdir $MAPDIR --launch-sites $LAUNCHSITES --max-zoom $MAXZOOM
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+altos-mapj
+altos-mapj-jdb
+altos-mapj-test
+*.jar
+*.stamp
+classes
--- /dev/null
+/*
+ * Copyright © 2018 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package altosmap;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+import org.altusmetrum.altoslib_13.*;
+
+public class AltosMap {
+
+ public final static int port = 16717;
+
+ public final static String protocol_version = "1.0.0";
+
+ String query_string;
+ String remote_addr;
+
+ public String reason_string(int code) {
+ switch (code) {
+ case 200:
+ return "OK";
+ case 400:
+ return "Bad Request";
+ case 403:
+ return "Forbidden";
+ case 404:
+ return "Not Found";
+ case 408:
+ return "Request Timeout";
+ default:
+ return "Failure";
+ }
+ }
+
+ public void write_status(int status) {
+ System.out.printf("Status: %d %s\n", status, reason_string(status));
+ }
+
+ public void write_type(String type) {
+ System.out.printf("Content-Type: %s\n", type);
+ }
+
+ public void fail(int status, String reason) {
+ write_status(status);
+ write_type("text/html");
+ System.out.printf("\n");
+ System.out.printf("<html>\n");
+ System.out.printf("<head><title>Map Fetch Failure</title></head>\n");
+ System.out.printf("<body>%s</body>\n", reason);
+ System.out.printf("</html>\n");
+ System.exit(1);
+ }
+
+ public void process() {
+ query_string = System.getenv("QUERY_STRING");
+
+ if (query_string == null)
+ fail(400, "Missing query string");
+
+ remote_addr = System.getenv("REMOTE_ADDR");
+
+ if (remote_addr == null)
+ fail(400, "Missing remote address");
+
+ String[] queries = query_string.split("&");
+
+ double lon = AltosLib.MISSING;
+ double lat = AltosLib.MISSING;
+ int zoom = AltosLib.MISSING;
+ String version = null;
+
+ try {
+ for (String query : queries) {
+ String[] q = query.split("=");
+ if (q.length >= 2) {
+ String name = q[0];
+ String value = q[1];
+ if (name.equals("lon"))
+ lon = AltosParse.parse_double_net(value);
+ else if (name.equals("lat"))
+ lat = AltosParse.parse_double_net(value);
+ else if (name.equals("zoom"))
+ zoom = AltosParse.parse_int(value);
+ else if (name.equals("version"))
+ version = value;
+ else
+ fail(400, String.format("Extra query param \"%s\"", query));
+ }
+ }
+ } catch (ParseException pe) {
+ fail(400, String.format("Invalid query: %s", pe.toString()));
+ }
+
+ if (version != null) {
+ System.out.printf("Content-Type: text/plain\n");
+ System.out.printf("\n");
+ System.out.printf("%s\n", protocol_version);
+ } else {
+ if (lon == AltosLib.MISSING)
+ fail(400, "Missing longitude");
+ if (lat == AltosLib.MISSING)
+ fail(400, "Missing latitude");
+ if (zoom == AltosLib.MISSING)
+ fail(400, "Missing zoom");
+
+ try {
+ Socket socket = null;
+ int tries = 0;
+
+ while (tries < 10 && socket == null) {
+ try {
+ socket = new Socket(InetAddress.getLoopbackAddress(), port);
+ } catch (IOException ie) {
+ Thread.sleep(100);
+ tries++;
+ }
+ }
+
+ AltosJson request = new AltosJson();
+
+ request.put("lat", lat);
+ request.put("lon", lon);
+ request.put("zoom", zoom);
+ request.put("remote_addr", remote_addr);
+
+ Writer writer = new PrintWriter(socket.getOutputStream());
+ request.write(writer);
+ writer.flush();
+
+ AltosJson reply = AltosJson.fromInputStream(socket.getInputStream());
+
+ int status = reply.get_int("status", 400);
+
+ if (status != 200)
+ fail(status, "Bad cache status");
+
+ String filename = reply.get_string("filename", null);
+ try {
+ File file = new File(filename);
+ long length = file.length();
+ FileInputStream in = new FileInputStream(file);
+ String content_type = reply.get_string("content_type", null);
+ System.out.printf("Content-Type: %s\n", content_type);
+ System.out.printf("Content-Length: %d\n", file.length());
+ System.out.printf("\n");
+ byte[] buf = new byte[4096];
+ int bytes_read;
+ while ((bytes_read = in.read(buf)) > 0)
+ System.out.write(buf);
+ } catch (IOException ie) {
+ fail(404, String.format("IO Exception: %s", ie.toString()));
+ }
+ } catch (Exception e) {
+ fail(404, String.format("Exception %s", e.toString()));
+ }
+ }
+ }
+
+ public AltosMap() {
+ }
+
+ public static void main(final String[] args) {
+
+ new AltosMap().process();
+
+ }
+}
--- /dev/null
+JAVAROOT=classes
+AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6
+
+altoslibdir=$(libdir)/altos
+
+CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="$(JAVAROOT):../../altoslib/*"
+
+bin_SCRIPTS=altos-mapj
+
+altosmap_JAVA = \
+ AltosMap.java
+
+ALTOSLIB_CLASS=\
+ altoslib_$(ALTOSLIB_VERSION).jar
+
+JAR=altosmap.jar
+
+FATJAR=altosmap-fat.jar
+
+all-local: classes/altosmap $(JAR) altos-mapj altos-mapj-test altos-mapj-jdb
+
+install-altosmapJAVA: altosmap.jar
+ @$(NORMAL_INSTALL)
+ test -z "$(altosmapdir)" || $(MKDIR_P) "$(DESTDIR)$(altosmapdir)"
+ echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(altosmapdir)/altosmap.jar'"; \
+ $(INSTALL_DATA) "$<" "$(DESTDIR)$(altosmapdir)"
+
+classes/altosmap:
+ mkdir -p classes/altosmap
+
+$(JAR): classaltosmap.stamp Manifest.txt $(ALTOSLIB_CLASS)
+ jar cfm $@ Manifest.txt \
+ -C classes altosmap
+
+altosmapdir=$(datadir)/java
+
+$(FATJAR): classaltosmap.stamp Manifest-fat.txt $(ALTOSLIB_CLASS)
+ jar cfm $@ Manifest-fat.txt \
+ -C classes altosmap
+
+altos-mapj: Makefile
+ echo "#!/bin/sh" > $@
+ echo 'exec java -Djava.library.path="$(altoslibdir)" -jar "$(altosmapdir)/altosmap.jar" "$$@"' >> $@
+ chmod +x $@
+
+altos-mapj-test: Makefile
+ echo '#!/bin/sh' > $@
+ echo 'dir="$$(dirname $$0)"' >> $@
+ echo 'cd "$$dir"' >> $@
+ echo 'altosmap="$$(pwd -P)"' >> $@
+ echo 'exec java -jar "$$altosmap/altosmap.jar" "$$@"' >> $@
+ chmod +x $@
+
+altos-mapj-jdb: Makefile
+ echo "#!/bin/sh" > $@
+ echo 'exec jdb altosmap/AltosMap "$$@"' >> $@
+ chmod +x $@
+
+$(ALTOSLIB_CLASS):
+ -rm -f "$@"
+ $(LN_S) ../../altoslib/"$@" .
+
--- /dev/null
+Main-Class: altosmap.AltosMap
+Class-Path: altoslib_13.jar
--- /dev/null
+#!/bin/sh
+# map-N43.799102,W120.586281-hybrid-20.jpg
+export QUERY_STRING="lat=43.799102&lon=-120.586281&zoom=20"
+export REMOTE_ADDR="127.0.0.1"
+./altos-mapj-test
+
MACOSX_INFO_PLIST=Info.plist
MACOSX_README=ReadMe-Mac.rtf
-MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVERS) $(MACOSX_README) $(DOC) $(MACOSX_ICONS)
+MACOSX_INSTALL=../altosui/install-macosx
+MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_DRIVERS) $(MACOSX_README) $(DOC) $(MACOSX_ICONS) $(MACOSX_INSTALL)
$(MACOSX_DRIVER_0):
wget -O $@ $(MACOSX_DRIVER_0_URL)
-rm -rf macosx
mkdir macosx
cp -a MicroPeak.app macosx/
- cp -a $(MACOSX_README) macosx/ReadMe.rtf
+ cp -a $(MACOSX_README) macosx/ReadMe-MicroPeak.rtf
+ cp -a $(MACOSX_INSTALL) macosx
cp -a $(DOC) macosx
cp -p Info.plist macosx/MicroPeak.app/Contents
cp -p $(MACOSX_DRIVERS) macosx
import java.lang.*;
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroData {
public int ground_pressure;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroDeviceDialog extends AltosDeviceDialog {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog, WindowListener {
MicroPeak owner;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroExport extends JFileChooser {
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroFile {
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroFileChooser extends JFileChooser {
JFrame frame;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroFrame extends AltosUIFrame {
static String[] micro_icon_names = {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroPeak extends MicroFrame implements ActionListener, ItemListener, AltosFilterListener {
import java.awt.*;
import java.io.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroRaw extends JTextArea implements AltosFontListener {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroSave extends JFileChooser {
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroSerial extends InputStream {
SWIGTYPE_p_altos_file file;
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public interface MicroSerialLog {
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class MicroUSB extends altos_device implements AltosDevice {
return isFTDI() || isMicro();
}
+ public int hashCode() {
+ return getVendor() ^ getProduct() ^ getSerial() ^ getPath().hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o == null)
+ return false;
+
+ if (!(o instanceof MicroUSB))
+ return false;
+
+ MicroUSB other = (MicroUSB) o;
+
+ return getVendor() == other.getVendor() &&
+ getProduct() == other.getProduct() &&
+ getSerial() == other.getSerial() &&
+ getPath().equals(other.getPath());
+ }
+
static java.util.List<MicroUSB> list() {
if (!load_library())
return null;
-{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510
-{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
-{\colortbl;\red255\green255\blue255;}
-\margl1440\margr1440\vieww10800\viewh8400\viewkind0
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
+{\rtf1\ansi\deff3\adeflang1025
+{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\froman\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f6\froman\fprq2\fcharset0 Helvetica LT Std;}{\f7\fnil\fprq2\fcharset0 SimSun;}{\f8\fnil\fprq2\fcharset0 Arial Unicode MS;}{\f9\fnil\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f10\fnil\fprq2\fcharset0 Helvetica LT Std;}{\f11\fnil\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+{\stylesheet{\s0\snext0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033 Normal;}
+{\s15\sbasedon0\snext16\ql\nowidctlpar\hyphpar0\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f4\fs28 Heading;}
+{\s16\sbasedon0\snext16\sl276\slmult1\ql\nowidctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24 Text Body;}
+{\s17\sbasedon16\snext17\sl276\slmult1\ql\nowidctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24 List;}
+{\s18\sbasedon0\snext18\ql\nowidctlpar\hyphpar0\sb120\sa120\ltrpar\cf0\i\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24 Caption;}
+{\s19\sbasedon0\snext19\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24 Index;}
+}{\*\listtable{\list\listtemplateid1
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'00);}{\levelnumbers\'01;}\fi-360\li720}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'01.;}{\levelnumbers\'01;}\fi-360\li1080}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'02.;}{\levelnumbers\'01;}\fi-360\li1440}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'03.;}{\levelnumbers\'01;}\fi-360\li1800}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'04.;}{\levelnumbers\'01;}\fi-360\li2160}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'05.;}{\levelnumbers\'01;}\fi-360\li2520}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'06.;}{\levelnumbers\'01;}\fi-360\li2880}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'07.;}{\levelnumbers\'01;}\fi-360\li3240}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'08.;}{\levelnumbers\'01;}\fi-360\li3600}\listid1}
+{\list\listtemplateid2
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}\listid2}
+}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}{\*\generator LibreOffice/6.1.2.1$Linux_X86_64 LibreOffice_project/10$Build-1}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr2018\mo10\dy5\hr19\min22}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab720
+\hyphauto0\viewscale150
+{\*\pgdsctbl
+{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}}
+\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
+{\*\ftnsep\chftnsep}\pgndec\pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f5\hich\af5
+Installing MicroPeak software for Mac OS X computers}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\cf0\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f5\hich\af5
-\f0\fs24 \cf0 Installing MicroPeak software for Mac OS X computers\
-\
-There are two files included in the Mac OS X distribution:\
-\
- 1) The MicroPeak application\
-\
- 2) The FTDI device drivers\
-\
-As with most Mac OS X applications, install MicroPeak by dragging it from the distribution disk image to a suitable place on your computer.\
-\
-To communicate with the MicroPeak serial adapter, you need to installed the FTDI device drivers, which is done by double-clicking on the FTDIUSBSerialDriver disk image. Inside that is the FTDI USB Serial Driver package. Double click on that and it will guide you through the installation process.\
-\
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+The MicroPeak distribution for Mac OS X consists of:}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033{\listtext\pard\plain 1)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+The MicroPeak application}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033{\listtext\pard\plain 2)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af7\langfe1081\dbch\af10\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+Mac OS X driver for FTDI USB devices}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\li720\ri0\lin720\rin0\fi0\cf0\kerning1\dbch\af8\langfe1081\dbch\af10\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f6\hich\af6
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af7\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+Install the MicroPeak application by control-clicking the install-macosx script and selecting \u8220\'93Open\u8221\'94 from the menu. This will display a dialog asking if you are sure you want to open it. Select \u8220\'93Open\u8221\'94 from the dialog to execute the script. This will install the software, documentation and firmware in your home Applications/AltOS folder. You can move it afte}{\cf0\kerning1\dbch\af7\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+r}{\cf0\kerning1\dbch\af7\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\lang1033\loch\f5\hich\af5
+wards if you choose.}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\cf0\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f5\hich\af5
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f5\hich\af5
+To communicate with the MicroPeak serial adapter, you need to installed the FTDI device drivers, which is done by double-clicking on the FTDIUSBSerialDriver disk image. Inside that is the FTDI USB Serial Driver package. Double click on that and it will guide you through the installation process.}
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\cf0\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f5\hich\af5
+
+\par \pard\plain \s0\ql\nowidctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af8\langfe1081\dbch\af11\afs24\alang1033\loch\f3\fs24\lang1033\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af8\langfe1081\dbch\af9\afs24\alang1033\rtlch \ltrch\loch\fs24\loch\f5\hich\af5
Thanks for choosing AltusMetrum products!}
+\par }
\ No newline at end of file
telerepeat-v1.0
ARMM3DIRS=\
- fox1ihu fox1ihu/flash-loader \
easymega-v1.0 easymega-v1.0/flash-loader \
telemega-v0.1 telemega-v0.1/flash-loader \
telemega-v1.0 telemega-v1.0/flash-loader \
#define PRINTD(l,...)
#endif
-uint8_t ao_mma655x_spi_index = AO_MMA655X_SPI_INDEX;
-
static void
ao_mma655x_start(void) {
ao_spi_get_bit(AO_MMA655X_CS_PORT,
uint8_t cnt;
uint16_t n_rem = 0;
uint8_t n_bit;
+ uint8_t *p = prom;
prom[15] = 0;
for (cnt = 0; cnt < 16; cnt++) {
- n_rem ^= prom[cnt];
+ n_rem ^= *p++;
for (n_bit = 8; n_bit > 0; n_bit--) {
if (n_rem & 0x8000)
n_rem = (n_rem << 1) ^ 0x3000;
return n_rem;
}
+static int
+ao_ms5607_prom_valid(uint8_t *prom)
+{
+ uint8_t crc;
+ int i;
+ uint8_t *p;
+
+ /* Look for a value other than 0x0000 or 0xffff */
+ p = prom;
+ for (i = 0; i < 16; i++)
+ if (*p++ + 1 > 1)
+ break;
+ if (i == 16)
+ return FALSE;
+
+ crc = ao_ms5607_crc(prom);
+ if (crc != (prom[15] & 0xf))
+ return FALSE;
+
+ return TRUE;
+}
+
static void
ao_ms5607_prom_read(__xdata struct ao_ms5607_prom *prom)
{
- uint8_t addr;
- uint8_t crc;
- __xdata uint16_t *r;
+ uint8_t addr;
+ uint16_t *r;
r = (__xdata uint16_t *) prom;
for (addr = 0; addr < 8; addr++) {
ao_ms5607_stop();
r++;
}
- crc = ao_ms5607_crc((uint8_t *) prom);
- if (crc != (((uint8_t *) prom)[15] & 0xf)) {
-#if HAS_TASK
- printf ("MS5607 PROM CRC error (computed %x actual %x)\n",
- crc, (((uint8_t *) prom)[15] & 0xf));
- flush();
-#endif
+
+ if (!ao_ms5607_prom_valid((uint8_t *) prom))
ao_panic(AO_PANIC_SELF_TEST_MS5607);
- }
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* Byte swap */
r = (uint16_t *) prom;
for (addr = 0; addr < 8; addr++) {
- uint16_t t = *r;
- *r++ = (t << 8) | (t >> 8);
+ uint8_t *t = (uint8_t *) r;
+ uint8_t a = t[0];
+ t[0] = t[1];
+ t[1] = a;
+ r++;
}
#endif
}
AO_WATCHDOG_PORT->odr ^= (1 << AO_WATCHDOG_BIT); \
} while (0)
-#define HAS_TICK 1
+#define HAS_TICK 0
#include <ao_flash_stm_pins.h>
/* Attached signal, PB8 */
#if HAS_MONITOR
-extern const char const * const ao_state_names[];
+extern const char * const ao_state_names[];
#define AO_MONITOR_RING 8
if (ao_force_freq) {
ao_config.frequency = 434550;
ao_config.radio_cal = ao_radio_cal;
+#if HAS_RADIO_RATE
+ ao_config.radio_rate = AO_CONFIG_DEFAULT_RADIO_RATE;
+#endif
ao_xmemcpy(&ao_config.callsign, CODE_TO_XDATA(AO_CONFIG_DEFAULT_CALLSIGN),
sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1);
}
* structure.
*/
-__xdata ao_log_type log;
+__xdata ao_log_type ao_log_data;
static uint8_t
ao_log_csum(__xdata uint8_t *b) __reentrant
uint8_t
ao_log_check_data(void)
{
- if (ao_log_csum((uint8_t *) &log) != 0)
+ if (ao_log_csum((uint8_t *) &ao_log_data) != 0)
return 0;
return 1;
}
uint8_t
ao_log_check_clear(void)
{
- uint8_t *b = (uint8_t *) &log;
+ uint8_t *b = (uint8_t *) &ao_log_data;
uint8_t i;
for (i = 0; i < sizeof (ao_log_type); i++) {
ao_log_flight(uint8_t slot)
{
if (!ao_storage_read(ao_log_pos(slot),
- &log,
+ &ao_log_data,
sizeof (ao_log_type)))
return -(int16_t) (slot + 1);
if (ao_log_check_clear())
return 0;
- if (!ao_log_check_data() || log.type != AO_LOG_FLIGHT)
+ if (!ao_log_check_data() || ao_log_data.type != AO_LOG_FLIGHT)
return -(int16_t) (slot + 1);
- return log.u.flight.flight;
+ return ao_log_data.u.flight.flight;
}
#endif
#endif
#ifndef AO_LOG_UNCOMMON
-extern __xdata ao_log_type log;
+extern __xdata ao_log_type ao_log_data;
#define AO_LOG_SIZE sizeof(ao_log_type)
while (!ao_log_running)
ao_sleep(&ao_log_running);
- log.type = AO_LOG_FLIGHT;
- log.tick = ao_sample_tick;
+ ao_log_data.type = AO_LOG_FLIGHT;
+ ao_log_data.tick = ao_sample_tick;
#if HAS_ACCEL
- log.u.flight.ground_accel = ao_ground_accel;
+ ao_log_data.u.flight.ground_accel = ao_ground_accel;
#endif
- log.u.flight.flight = ao_flight_number;
- ao_log_write(&log);
+ ao_log_data.u.flight.flight = ao_flight_number;
+ ao_log_write(&ao_log_data);
/* Write the whole contents of the ring to the log
* when starting up.
for (;;) {
/* Write samples to EEPROM */
while (ao_log_data_pos != ao_sample_data) {
- log.tick = ao_data_ring[ao_log_data_pos].tick;
- if ((int16_t) (log.tick - next_sensor) >= 0) {
- log.type = AO_LOG_SENSOR;
- log.u.sensor.accel = ao_data_ring[ao_log_data_pos].adc.accel;
- log.u.sensor.pres = ao_data_ring[ao_log_data_pos].adc.pres;
- ao_log_write(&log);
+ ao_log_data.tick = ao_data_ring[ao_log_data_pos].tick;
+ if ((int16_t) (ao_log_data.tick - next_sensor) >= 0) {
+ ao_log_data.type = AO_LOG_SENSOR;
+ ao_log_data.u.sensor.accel = ao_data_ring[ao_log_data_pos].adc.accel;
+ ao_log_data.u.sensor.pres = ao_data_ring[ao_log_data_pos].adc.pres;
+ ao_log_write(&ao_log_data);
if (ao_log_state <= ao_flight_coast)
- next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_ASCENT;
else
- next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_DESCENT;
}
- if ((int16_t) (log.tick - next_other) >= 0) {
- log.type = AO_LOG_TEMP_VOLT;
- log.u.temp_volt.temp = ao_data_ring[ao_log_data_pos].adc.temp;
- log.u.temp_volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
- ao_log_write(&log);
- log.type = AO_LOG_DEPLOY;
- log.u.deploy.drogue = ao_data_ring[ao_log_data_pos].adc.sense_d;
- log.u.deploy.main = ao_data_ring[ao_log_data_pos].adc.sense_m;
- ao_log_write(&log);
- next_other = log.tick + AO_OTHER_INTERVAL;
+ if ((int16_t) (ao_log_data.tick - next_other) >= 0) {
+ ao_log_data.type = AO_LOG_TEMP_VOLT;
+ ao_log_data.u.temp_volt.temp = ao_data_ring[ao_log_data_pos].adc.temp;
+ ao_log_data.u.temp_volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
+ ao_log_write(&ao_log_data);
+ ao_log_data.type = AO_LOG_DEPLOY;
+ ao_log_data.u.deploy.drogue = ao_data_ring[ao_log_data_pos].adc.sense_d;
+ ao_log_data.u.deploy.main = ao_data_ring[ao_log_data_pos].adc.sense_m;
+ ao_log_write(&ao_log_data);
+ next_other = ao_log_data.tick + AO_OTHER_INTERVAL;
}
ao_log_data_pos = ao_data_ring_next(ao_log_data_pos);
}
/* Write state change to EEPROM */
if (ao_flight_state != ao_log_state) {
ao_log_state = ao_flight_state;
- log.type = AO_LOG_STATE;
- log.tick = ao_sample_tick;
- log.u.state.state = ao_log_state;
- log.u.state.reason = 0;
- ao_log_write(&log);
+ ao_log_data.type = AO_LOG_STATE;
+ ao_log_data.tick = ao_sample_tick;
+ ao_log_data.u.state.state = ao_log_state;
+ ao_log_data.u.state.reason = 0;
+ ao_log_write(&ao_log_data);
if (ao_log_state == ao_flight_landed)
ao_log_stop();
void
ao_log_gps_flight(void)
{
- log.type = AO_LOG_FLIGHT;
- log.tick = ao_time();
- log.u.flight.flight = ao_flight_number;
- ao_log_write(&log);
+ ao_log_data.type = AO_LOG_FLIGHT;
+ ao_log_data.tick = ao_time();
+ ao_log_data.u.flight.flight = ao_flight_number;
+ ao_log_write(&ao_log_data);
}
void
ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data)
{
- log.tick = tick;
- log.type = AO_LOG_GPS_TIME;
- log.u.gps.latitude = gps_data->latitude;
- log.u.gps.longitude = gps_data->longitude;
- log.u.gps.altitude_low = gps_data->altitude_low;
- log.u.gps.altitude_high = gps_data->altitude_high;
+ ao_log_data.tick = tick;
+ ao_log_data.type = AO_LOG_GPS_TIME;
+ ao_log_data.u.gps.latitude = gps_data->latitude;
+ ao_log_data.u.gps.longitude = gps_data->longitude;
+ ao_log_data.u.gps.altitude_low = gps_data->altitude_low;
+ ao_log_data.u.gps.altitude_high = gps_data->altitude_high;
- log.u.gps.hour = gps_data->hour;
- log.u.gps.minute = gps_data->minute;
- log.u.gps.second = gps_data->second;
- log.u.gps.flags = gps_data->flags;
- log.u.gps.year = gps_data->year;
- log.u.gps.month = gps_data->month;
- log.u.gps.day = gps_data->day;
- log.u.gps.course = gps_data->course;
- log.u.gps.ground_speed = gps_data->ground_speed;
- log.u.gps.climb_rate = gps_data->climb_rate;
- log.u.gps.pdop = gps_data->pdop;
- log.u.gps.hdop = gps_data->hdop;
- log.u.gps.vdop = gps_data->vdop;
- log.u.gps.mode = gps_data->mode;
- ao_log_write(&log);
+ ao_log_data.u.gps.hour = gps_data->hour;
+ ao_log_data.u.gps.minute = gps_data->minute;
+ ao_log_data.u.gps.second = gps_data->second;
+ ao_log_data.u.gps.flags = gps_data->flags;
+ ao_log_data.u.gps.year = gps_data->year;
+ ao_log_data.u.gps.month = gps_data->month;
+ ao_log_data.u.gps.day = gps_data->day;
+ ao_log_data.u.gps.course = gps_data->course;
+ ao_log_data.u.gps.ground_speed = gps_data->ground_speed;
+ ao_log_data.u.gps.climb_rate = gps_data->climb_rate;
+ ao_log_data.u.gps.pdop = gps_data->pdop;
+ ao_log_data.u.gps.hdop = gps_data->hdop;
+ ao_log_data.u.gps.vdop = gps_data->vdop;
+ ao_log_data.u.gps.mode = gps_data->mode;
+ ao_log_write(&ao_log_data);
}
void
{
uint8_t c, n, i;
- log.tick = tick;
- log.type = AO_LOG_GPS_SAT;
+ ao_log_data.tick = tick;
+ ao_log_data.type = AO_LOG_GPS_SAT;
i = 0;
n = gps_tracking_data->channels;
for (c = 0; c < n; c++)
- if ((log.u.gps_sat.sats[i].svid = gps_tracking_data->sats[c].svid))
+ if ((ao_log_data.u.gps_sat.sats[i].svid = gps_tracking_data->sats[c].svid))
{
- log.u.gps_sat.sats[i].c_n = gps_tracking_data->sats[c].c_n_1;
+ ao_log_data.u.gps_sat.sats[i].c_n = gps_tracking_data->sats[c].c_n_1;
i++;
if (i >= 12)
break;
}
- log.u.gps_sat.channels = i;
- ao_log_write(&log);
+ ao_log_data.u.gps_sat.channels = i;
+ ao_log_write(&ao_log_data);
}
int8_t
ao_log_check(uint32_t pos)
{
if (!ao_storage_read(pos,
- &log,
+ &ao_log_data,
sizeof (struct ao_log_gps)))
return AO_LOG_INVALID;
ao_sleep(&ao_log_running);
#if HAS_FLIGHT
- log.type = AO_LOG_FLIGHT;
- log.tick = ao_sample_tick;
+ ao_log_data.type = AO_LOG_FLIGHT;
+ ao_log_data.tick = ao_sample_tick;
#if HAS_ACCEL
- log.u.flight.ground_accel = ao_ground_accel;
+ ao_log_data.u.flight.ground_accel = ao_ground_accel;
#endif
#if HAS_GYRO
- log.u.flight.ground_accel_along = ao_ground_accel_along;
- log.u.flight.ground_accel_across = ao_ground_accel_across;
- log.u.flight.ground_accel_through = ao_ground_accel_through;
- log.u.flight.ground_roll = ao_ground_roll;
- log.u.flight.ground_pitch = ao_ground_pitch;
- log.u.flight.ground_yaw = ao_ground_yaw;
+ ao_log_data.u.flight.ground_accel_along = ao_ground_accel_along;
+ ao_log_data.u.flight.ground_accel_across = ao_ground_accel_across;
+ ao_log_data.u.flight.ground_accel_through = ao_ground_accel_through;
+ ao_log_data.u.flight.ground_roll = ao_ground_roll;
+ ao_log_data.u.flight.ground_pitch = ao_ground_pitch;
+ ao_log_data.u.flight.ground_yaw = ao_ground_yaw;
#endif
- log.u.flight.ground_pres = ao_ground_pres;
- log.u.flight.flight = ao_flight_number;
- ao_log_write(&log);
+ ao_log_data.u.flight.ground_pres = ao_ground_pres;
+ ao_log_data.u.flight.flight = ao_flight_number;
+ ao_log_write(&ao_log_data);
#endif
/* Write the whole contents of the ring to the log
for (;;) {
/* Write samples to EEPROM */
while (ao_log_data_pos != ao_data_head) {
- log.tick = ao_data_ring[ao_log_data_pos].tick;
- if ((int16_t) (log.tick - next_sensor) >= 0) {
- log.type = AO_LOG_SENSOR;
+ ao_log_data.tick = ao_data_ring[ao_log_data_pos].tick;
+ if ((int16_t) (ao_log_data.tick - next_sensor) >= 0) {
+ ao_log_data.type = AO_LOG_SENSOR;
#if HAS_MS5607
- log.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres;
- log.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp;
+ ao_log_data.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres;
+ ao_log_data.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp;
#endif
#if HAS_MPU6000
- log.u.sensor.accel_x = ao_data_ring[ao_log_data_pos].mpu6000.accel_x;
- log.u.sensor.accel_y = ao_data_ring[ao_log_data_pos].mpu6000.accel_y;
- log.u.sensor.accel_z = ao_data_ring[ao_log_data_pos].mpu6000.accel_z;
- log.u.sensor.gyro_x = ao_data_ring[ao_log_data_pos].mpu6000.gyro_x;
- log.u.sensor.gyro_y = ao_data_ring[ao_log_data_pos].mpu6000.gyro_y;
- log.u.sensor.gyro_z = ao_data_ring[ao_log_data_pos].mpu6000.gyro_z;
+ ao_log_data.u.sensor.accel_x = ao_data_ring[ao_log_data_pos].mpu6000.accel_x;
+ ao_log_data.u.sensor.accel_y = ao_data_ring[ao_log_data_pos].mpu6000.accel_y;
+ ao_log_data.u.sensor.accel_z = ao_data_ring[ao_log_data_pos].mpu6000.accel_z;
+ ao_log_data.u.sensor.gyro_x = ao_data_ring[ao_log_data_pos].mpu6000.gyro_x;
+ ao_log_data.u.sensor.gyro_y = ao_data_ring[ao_log_data_pos].mpu6000.gyro_y;
+ ao_log_data.u.sensor.gyro_z = ao_data_ring[ao_log_data_pos].mpu6000.gyro_z;
#endif
#if HAS_HMC5883
- log.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].hmc5883.x;
- log.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].hmc5883.z;
- log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;
+ ao_log_data.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].hmc5883.x;
+ ao_log_data.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].hmc5883.z;
+ ao_log_data.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;
#endif
#if HAS_MPU9250
- log.u.sensor.accel_x = ao_data_ring[ao_log_data_pos].mpu9250.accel_x;
- log.u.sensor.accel_y = ao_data_ring[ao_log_data_pos].mpu9250.accel_y;
- log.u.sensor.accel_z = ao_data_ring[ao_log_data_pos].mpu9250.accel_z;
- log.u.sensor.gyro_x = ao_data_ring[ao_log_data_pos].mpu9250.gyro_x;
- log.u.sensor.gyro_y = ao_data_ring[ao_log_data_pos].mpu9250.gyro_y;
- log.u.sensor.gyro_z = ao_data_ring[ao_log_data_pos].mpu9250.gyro_z;
- log.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].mpu9250.mag_x;
- log.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].mpu9250.mag_z;
- log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].mpu9250.mag_y;
+ ao_log_data.u.sensor.accel_x = ao_data_ring[ao_log_data_pos].mpu9250.accel_x;
+ ao_log_data.u.sensor.accel_y = ao_data_ring[ao_log_data_pos].mpu9250.accel_y;
+ ao_log_data.u.sensor.accel_z = ao_data_ring[ao_log_data_pos].mpu9250.accel_z;
+ ao_log_data.u.sensor.gyro_x = ao_data_ring[ao_log_data_pos].mpu9250.gyro_x;
+ ao_log_data.u.sensor.gyro_y = ao_data_ring[ao_log_data_pos].mpu9250.gyro_y;
+ ao_log_data.u.sensor.gyro_z = ao_data_ring[ao_log_data_pos].mpu9250.gyro_z;
+ ao_log_data.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].mpu9250.mag_x;
+ ao_log_data.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].mpu9250.mag_z;
+ ao_log_data.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].mpu9250.mag_y;
#endif
- log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
- ao_log_write(&log);
+ ao_log_data.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
+ ao_log_write(&ao_log_data);
if (ao_log_state <= ao_flight_coast)
- next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_ASCENT;
else
- next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_DESCENT;
}
- if ((int16_t) (log.tick - next_other) >= 0) {
- log.type = AO_LOG_TEMP_VOLT;
- log.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
- log.u.volt.v_pbatt = ao_data_ring[ao_log_data_pos].adc.v_pbatt;
- log.u.volt.n_sense = AO_ADC_NUM_SENSE;
+ if ((int16_t) (ao_log_data.tick - next_other) >= 0) {
+ ao_log_data.type = AO_LOG_TEMP_VOLT;
+ ao_log_data.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
+ ao_log_data.u.volt.v_pbatt = ao_data_ring[ao_log_data_pos].adc.v_pbatt;
+ ao_log_data.u.volt.n_sense = AO_ADC_NUM_SENSE;
for (i = 0; i < AO_ADC_NUM_SENSE; i++)
- log.u.volt.sense[i] = ao_data_ring[ao_log_data_pos].adc.sense[i];
- log.u.volt.pyro = ao_pyro_fired;
- ao_log_write(&log);
- next_other = log.tick + AO_OTHER_INTERVAL;
+ ao_log_data.u.volt.sense[i] = ao_data_ring[ao_log_data_pos].adc.sense[i];
+ ao_log_data.u.volt.pyro = ao_pyro_fired;
+ ao_log_write(&ao_log_data);
+ next_other = ao_log_data.tick + AO_OTHER_INTERVAL;
}
ao_log_data_pos = ao_data_ring_next(ao_log_data_pos);
}
/* Write state change to EEPROM */
if (ao_flight_state != ao_log_state) {
ao_log_state = ao_flight_state;
- log.type = AO_LOG_STATE;
- log.tick = ao_time();
- log.u.state.state = ao_log_state;
- log.u.state.reason = 0;
- ao_log_write(&log);
+ ao_log_data.type = AO_LOG_STATE;
+ ao_log_data.tick = ao_time();
+ ao_log_data.u.state.state = ao_log_state;
+ ao_log_data.u.state.reason = 0;
+ ao_log_write(&ao_log_data);
if (ao_log_state == ao_flight_landed)
ao_log_stop();
ao_sleep(&ao_log_running);
#if HAS_FLIGHT
- log.type = AO_LOG_FLIGHT;
- log.tick = ao_sample_tick;
+ ao_log_data.type = AO_LOG_FLIGHT;
+ ao_log_data.tick = ao_sample_tick;
#if HAS_ACCEL
- log.u.flight.ground_accel = ao_ground_accel;
+ ao_log_data.u.flight.ground_accel = ao_ground_accel;
#endif
- log.u.flight.ground_pres = ao_ground_pres;
- log.u.flight.flight = ao_flight_number;
- ao_log_write(&log);
+ ao_log_data.u.flight.ground_pres = ao_ground_pres;
+ ao_log_data.u.flight.flight = ao_flight_number;
+ ao_log_write(&ao_log_data);
#endif
/* Write the whole contents of the ring to the log
for (;;) {
/* Write samples to EEPROM */
while (ao_log_data_pos != ao_data_head) {
- log.tick = ao_data_ring[ao_log_data_pos].tick;
- if ((int16_t) (log.tick - next_sensor) >= 0) {
- log.type = AO_LOG_SENSOR;
+ ao_log_data.tick = ao_data_ring[ao_log_data_pos].tick;
+ if ((int16_t) (ao_log_data.tick - next_sensor) >= 0) {
+ ao_log_data.type = AO_LOG_SENSOR;
#if HAS_MS5607
- log.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres;
- log.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp;
+ ao_log_data.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres;
+ ao_log_data.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp;
#endif
#if HAS_ACCEL
- log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
+ ao_log_data.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
#endif
- ao_log_write(&log);
+ ao_log_write(&ao_log_data);
if (ao_log_state <= ao_flight_coast)
- next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_ASCENT;
else
- next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_DESCENT;
}
- if ((int16_t) (log.tick - next_other) >= 0) {
- log.type = AO_LOG_TEMP_VOLT;
- log.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
- log.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a;
- log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m;
- ao_log_write(&log);
- next_other = log.tick + AO_OTHER_INTERVAL;
+ if ((int16_t) (ao_log_data.tick - next_other) >= 0) {
+ ao_log_data.type = AO_LOG_TEMP_VOLT;
+ ao_log_data.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
+ ao_log_data.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a;
+ ao_log_data.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m;
+ ao_log_write(&ao_log_data);
+ next_other = ao_log_data.tick + AO_OTHER_INTERVAL;
}
ao_log_data_pos = ao_data_ring_next(ao_log_data_pos);
}
/* Write state change to EEPROM */
if (ao_flight_state != ao_log_state) {
ao_log_state = ao_flight_state;
- log.type = AO_LOG_STATE;
- log.tick = ao_time();
- log.u.state.state = ao_log_state;
- log.u.state.reason = 0;
- ao_log_write(&log);
+ ao_log_data.type = AO_LOG_STATE;
+ ao_log_data.tick = ao_time();
+ ao_log_data.u.state.state = ao_log_state;
+ ao_log_data.u.state.reason = 0;
+ ao_log_write(&ao_log_data);
if (ao_log_state == ao_flight_landed)
ao_log_stop();
ao_sleep(&ao_log_running);
#if HAS_FLIGHT
- log.type = AO_LOG_FLIGHT;
- log.tick = ao_sample_tick;
- log.u.flight.flight = ao_flight_number;
- log.u.flight.ground_pres = ao_ground_pres;
- ao_log_write(&log);
+ ao_log_data.type = AO_LOG_FLIGHT;
+ ao_log_data.tick = ao_sample_tick;
+ ao_log_data.u.flight.flight = ao_flight_number;
+ ao_log_data.u.flight.ground_pres = ao_ground_pres;
+ ao_log_write(&ao_log_data);
#endif
/* Write the whole contents of the ring to the log
for (;;) {
/* Write samples to EEPROM */
while (ao_log_data_pos != ao_data_head) {
- log.tick = ao_data_ring[ao_log_data_pos].tick;
- if ((int16_t) (log.tick - next_sensor) >= 0) {
- log.type = AO_LOG_SENSOR;
- ao_log_pack24(log.u.sensor.pres,
+ ao_log_data.tick = ao_data_ring[ao_log_data_pos].tick;
+ if ((int16_t) (ao_log_data.tick - next_sensor) >= 0) {
+ ao_log_data.type = AO_LOG_SENSOR;
+ ao_log_pack24(ao_log_data.u.sensor.pres,
ao_data_ring[ao_log_data_pos].ms5607_raw.pres);
- ao_log_pack24(log.u.sensor.temp,
+ ao_log_pack24(ao_log_data.u.sensor.temp,
ao_data_ring[ao_log_data_pos].ms5607_raw.temp);
#if AO_LOG_FORMAT != AO_LOG_FORMAT_DETHERM
- log.u.sensor.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a;
- log.u.sensor.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m;
- log.u.sensor.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
+ ao_log_data.u.sensor.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a;
+ ao_log_data.u.sensor.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m;
+ ao_log_data.u.sensor.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
#endif
- ao_log_write(&log);
+ ao_log_write(&ao_log_data);
if (ao_log_state <= ao_flight_coast)
- next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_ASCENT;
else
- next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT;
+ next_sensor = ao_log_data.tick + AO_SENSOR_INTERVAL_DESCENT;
}
ao_log_data_pos = ao_data_ring_next(ao_log_data_pos);
}
/* Write state change to EEPROM */
if (ao_flight_state != ao_log_state) {
ao_log_state = ao_flight_state;
- log.type = AO_LOG_STATE;
- log.tick = ao_time();
- log.u.state.state = ao_log_state;
- log.u.state.reason = 0;
- ao_log_write(&log);
+ ao_log_data.type = AO_LOG_STATE;
+ ao_log_data.tick = ao_time();
+ ao_log_data.u.state.state = ao_log_state;
+ ao_log_data.u.state.reason = 0;
+ ao_log_write(&ao_log_data);
if (ao_log_state == ao_flight_landed)
ao_log_stop();
}
if (wake_input) {
ao_wakeup(&ao_usart_rx_fifo);
- if (stdin)
- ao_wakeup(&ao_stdin_ready);
+#if USE_SERIAL_0_STDIN
+ ao_wakeup(&ao_stdin_ready);
+#endif
}
}
#define HAS_TICK 1
#endif
+#if HAS_TICK || defined(AO_TIMER_HOOK)
+
#if HAS_TICK
volatile AO_TICK_TYPE ao_tick_count;
{
return ao_tick_count;
}
+#endif
#if AO_DATA_ALL
volatile __data uint8_t ao_data_interval = 1;
{
ao_validate_cur_stack();
if (stm_systick.csr & (1 << STM_SYSTICK_CSR_COUNTFLAG)) {
+#if HAS_TICK
++ao_tick_count;
+#endif
#if HAS_TASK_QUEUE
if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0)
ao_task_check_alarm((uint16_t) ao_tick_count);
#endif
static void
-_ao_usart_rx(struct ao_stm_usart *usart, int stdin)
+_ao_usart_rx(struct ao_stm_usart *usart, int is_stdin)
{
if (usart->reg->isr & (1 << STM_USART_ISR_RXNE)) {
usart->reg->icr = (1 << STM_USART_ICR_ORECF);
if (!ao_fifo_full(usart->rx_fifo)) {
ao_fifo_insert(usart->rx_fifo, usart->reg->rdr);
ao_wakeup(&usart->rx_fifo);
- if (stdin)
+ if (is_stdin)
ao_wakeup(&ao_stdin_ready);
#if HAS_SERIAL_SW_FLOW
/* If the fifo is nearly full, turn off RTS and wait
}
static void
-ao_usart_isr(struct ao_stm_usart *usart, int stdin)
+ao_usart_isr(struct ao_stm_usart *usart, int is_stdin)
{
- _ao_usart_rx(usart, stdin);
+ _ao_usart_rx(usart, is_stdin);
if (!_ao_usart_tx_start(usart))
usart->reg->cr1 &= ~(1<< STM_USART_CR1_TXEIE);
MACOSX_INFO_PLIST=Info.plist
MACOSX_README=ReadMe-Mac.rtf
-MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_README) $(DOC) $(MACOSX_ICONS)
+MACOSX_INSTALL=../altosui/install-macosx
+MACOSX_FILES=$(FAT_FILES) libaltos.dylib $(MACOSX_INFO_PLIST) $(MACOSX_README) $(DOC) $(MACOSX_ICONS) $(MACOSX_INSTALL)
MACOSX_EXTRA=$(FIRMWARE)
WINDOWS_FILES=$(FAT_FILES) altos.dll altos64.dll $(top_srcdir)/altusmetrum.inf $(top_srcdir)/altusmetrum.cat $(DOC) $(WINDOWS_ICONS)
-rm -rf macosx
mkdir macosx
cp -a TeleGPS.app macosx/
- cp -a $(MACOSX_README) macosx/ReadMe.rtf
+ cp -a $(MACOSX_README) macosx/ReadMe-TeleGPS.rtf
+ cp -a $(MACOSX_INSTALL) macosx
mkdir -p macosx/Doc
cp -a $(DOC) macosx/Doc
cp -p Info.plist macosx/TeleGPS.app/Contents
-{\rtf1\ansi\ansicpg1252\deff0\uc1
-{\fonttbl
-{\f0\fnil\fcharset0\fprq0\fttruetype Helvetica;}
-{\f1\fnil\fcharset0\fprq0\fttruetype Arial;}
-{\f2\fnil\fcharset0\fprq0\fttruetype Liberation Serif;}
-{\f3\fnil\fcharset0\fprq0\fttruetype Courier New;}}
-{\colortbl
-\red0\green0\blue0;
-\red255\green255\blue255;
-\red255\green255\blue255;}
-{\stylesheet
-{\s6\fi-431\li720\sbasedon28\snext28 Contents 1;}
-{\s7\fi-431\li1440\sbasedon28\snext28 Contents 2;}
-{\s1\fi-431\li720 Arrowhead List;}
-{\s27\fi-431\li720\sbasedon28 Lower Roman List;}
-{\s29\tx431\sbasedon20\snext28 Numbered Heading 1;}
-{\s30\tx431\sbasedon21\snext28 Numbered Heading 2;}
-{\s12\fi-431\li720 Diamond List;}
-{\s9\fi-431\li2880\sbasedon28\snext28 Contents 4;}
-{\s8\fi-431\li2160\sbasedon28\snext28 Contents 3;}
-{\s31\tx431\sbasedon22\snext28 Numbered Heading 3;}
-{\s32\fi-431\li720 Numbered List;}
-{\s15\sbasedon28 Endnote Text;}
-{\*\cs14\fs20\super Endnote Reference;}
-{\s4\fi-431\li720 Bullet List;}
-{\s5\tx1584\sbasedon29\snext28 Chapter Heading;}
-{\s35\fi-431\li720 Square List;}
-{\s11\fi-431\li720 Dashed List;}
-{\s22\sb440\sa60\f1\fs24\b\sbasedon28\snext28 Heading 3;}
-{\s37\fi-431\li720 Tick List;}
-{\s24\fi-431\li720 Heart List;}
-{\s40\fi-431\li720\sbasedon32 Upper Roman List;}
-{\s39\fi-431\li720\sbasedon32 Upper Case List;}
-{\s16\fi-288\li288\fs20\sbasedon28 Footnote;}
-{\s19\fi-431\li720 Hand List;}
-{\s18\fs20\sbasedon28 Footnote Text;}
-{\s20\sb440\sa60\f1\fs34\b\sbasedon28\snext28 Heading 1;}
-{\s21\sb440\sa60\f1\fs28\b\sbasedon28\snext28 Heading 2;}
-{\s10\qc\sb240\sa120\f1\fs32\b\sbasedon28\snext28 Contents Header;}
-{\s23\sb440\sa60\f1\fs24\b\sbasedon28\snext28 Heading 4;}
-{\s28\f2\fs24 Normal;}
-{\s26\fi-431\li720\sbasedon32 Lower Case List;}
-{\s2\li1440\ri1440\sa120\sbasedon28 Block Text;}
-{\s33\f3\sbasedon28 Plain Text;}
-{\s34\tx1584\sbasedon29\snext28 Section Heading;}
-{\s25\fi-431\li720 Implies List;}
-{\s3\fi-431\li720 Box List;}
-{\s36\fi-431\li720 Star List;}
-{\*\cs17\fs20\super Footnote Reference;}
-{\s38\fi-431\li720 Triangle List;}
-{\s13\fi-288\li288\sbasedon28 Endnote;}}
-\kerning0\cf0\ftnbj\fet2\ftnstart1\ftnnar\aftnnar\ftnstart1\aftnstart1\aenddoc\revprop3{\*\rdf}{\info\uc1}\deftab720\viewkind1\paperw12240\paperh15840\margl1440\margr1440\widowctrl
-\sectd\sbknone\colsx0\pgncont\ltrsect
-\pard\plain\ltrpar\ql\sl240\slmult1\itap0\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\f0\fs24\lang1033{\*\listtag0}\abinodiroverride\ltrch Installing }{\f0\fs24\lang1033{\*\listtag0}TeleGPS}{\f0\fs24\lang1033{\*\listtag0} software for Mac OS X computers}{\f0\fs24\lang1033{\*\listtag0}\par}
-\pard\plain\ltrpar\ql\sl240\slmult1\itap0\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\f0\fs24\lang1033{\*\listtag0}\par}
-\pard\plain\ltrpar\ql\sl240\slmult1\itap0\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\f0\fs24\lang1033{\*\listtag0}\abinodiroverride\ltrch As with most Mac OS X applications, install }{\f0\fs24\lang1033{\*\listtag0}TeleGPS}{\f0\fs24\lang1033{\*\listtag0} by dragging it from the distribution disk image to a suitable place on your computer.}{\f0\fs24\lang1033{\*\listtag0}\par}
-\pard\plain\ltrpar\ql\sl240\slmult1\itap0\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\f0\fs24\lang1033{\*\listtag0}\par}
-\pard\plain\ltrpar\ql\sl240\slmult1\itap0\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\f0\fs24\lang1033{\*\listtag0}\abinodiroverride\ltrch Thanks for choosing AltusMetrum products!}{\f0\fs24\lang1033{\*\listtag0}\par}}
\ No newline at end of file
+{\rtf1\ansi\deff3\adeflang1025
+{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\fswiss\fprq2\fcharset0 Arial;}{\f6\froman\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f7\froman\fprq2\fcharset0 Arial;}{\f8\froman\fprq2\fcharset0 Courier New;}{\f9\froman\fprq2\fcharset0 Helvetica LT Std;}{\f10\fnil\fprq2\fcharset0 SimSun;}{\f11\fnil\fprq2\fcharset0 Courier New;}{\f12\fnil\fprq2\fcharset0 Arial Unicode MS;}{\f13\fnil\fprq2\fcharset0 Arial;}{\f14\fnil\fprq2\fcharset0 Helvetica{\*\falt Arial};}{\f15\fnil\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f16\fnil\fprq2\fcharset0 Helvetica LT Std;}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+{\stylesheet{\s0\snext0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033 Normal;}
+{\s1\sbasedon19\snext1\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs34\lang1033 Heading 1;}
+{\s2\sbasedon19\snext2\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs28\lang1033 Heading 2;}
+{\s3\sbasedon19\snext3\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs24\lang1033 Heading 3;}
+{\s4\sbasedon19\snext4\ql\widctlpar\hyphpar0\sb440\sa60\keepn\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f5\fs24\lang1033 Heading 4;}
+{\*\cs15\snext15\super\fs20 Endnote Characters;}
+{\*\cs16\snext16\super\fs20 Endnote Anchor;}
+{\*\cs17\snext17\super\fs20 Footnote Characters;}
+{\*\cs18\snext18\super\fs20 Footnote Anchor;}
+{\s19\sbasedon0\snext20\ql\widctlpar\hyphpar0\sb240\sa120\keepn\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f4\fs28\lang1033 Heading;}
+{\s20\sbasedon0\snext20\sl276\slmult1\ql\widctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Text Body;}
+{\s21\sbasedon20\snext21\sl276\slmult1\ql\widctlpar\hyphpar0\sb0\sa140\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 List;}
+{\s22\sbasedon0\snext22\ql\widctlpar\hyphpar0\sb120\sa120\ltrpar\cf0\i\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Caption;}
+{\s23\sbasedon0\snext23\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Index;}
+{\s24\snext24\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Arrowhead List;}
+{\s25\sbasedon0\snext25\ql\widctlpar\hyphpar0\li1440\ri1440\lin1440\rin1440\fi0\sb0\sa120\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Block Text;}
+{\s26\snext26\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Box List;}
+{\s27\snext27\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Bullet List;}
+{\s28\snext28\tx1584\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af17\langfe2052\dbch\af12\afs24\alang1081\loch\f3\hich\af3\fs24\lang1033 Chapter Heading;}
+{\s29\sbasedon23\snext29\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 1;}
+{\s30\sbasedon23\snext30\ql\widctlpar\hyphpar0\li1440\ri0\lin1440\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 2;}
+{\s31\sbasedon23\snext31\ql\widctlpar\hyphpar0\li2160\ri0\lin2160\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 3;}
+{\s32\sbasedon23\snext32\ql\widctlpar\hyphpar0\li2880\ri0\lin2880\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Contents 4;}
+{\s33\snext33\qc\nowidctlpar\hyphpar0\sb240\sa120\ltrpar\cf0\b\kerning1\dbch\af12\langfe1081\dbch\af13\afs32\alang1033\loch\f7\fs24\lang1033 Contents Header;}
+{\s34\snext34\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Dashed List;}
+{\s35\snext35\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Diamond List;}
+{\s36\sbasedon0\snext36\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs24\lang1033 Endnote;}
+{\s37\sbasedon0\snext37\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f3\fs20\lang1033 Footnote;}
+{\s38\snext38\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Hand List;}
+{\s39\snext39\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Heart List;}
+{\s40\snext40\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Implies List;}
+{\s41\snext41\ql\widctlpar\li720\ri0\lin720\rin0\fi-431\ltrpar\hyphpar0\dbch\af11\cf0\kerning1\langfe2052\dbch\af12\afs24\alang1081\loch\f6\fs24\lang1033 Lower Case List;}
+{\s42\snext42\ql\nowidctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Lower Roman List;}
+{\s43\snext43\ql\nowidctlpar\tx431\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Numbered Heading 1;}
+{\s44\snext44\ql\nowidctlpar\tx431\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Numbered Heading 2;}
+{\s45\snext45\ql\nowidctlpar\tx431\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24\lang1033 Numbered Heading 3;}
+{\s46\snext46\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Numbered List;}
+{\s47\sbasedon0\snext47\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f8\fs24\lang1033 Plain Text;}
+{\s48\sbasedon43\snext48\ql\nowidctlpar\tx1584\hyphpar0\ltrpar\cf0\kerning1\dbch\af12\langfe1081\dbch\af15\afs24\alang1033\loch\f3\fs24 Section Heading;}
+{\s49\snext49\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Square List;}
+{\s50\snext50\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Star List;}
+{\s51\snext51\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Tick List;}
+{\s52\snext52\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f6\fs24\lang1033 Triangle List;}
+{\s53\sbasedon46\snext53\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f6\fs24\lang1033 Upper Case List;}
+{\s54\sbasedon46\snext54\ql\widctlpar\hyphpar0\li720\ri0\lin720\rin0\fi-431\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\loch\f6\fs24\lang1033 Upper Roman List;}
+}{\*\listtable{\list\listtemplateid1
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'00);}{\levelnumbers\'01;}\fi-360\li720}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'01.;}{\levelnumbers\'01;}\fi-360\li1080}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'02.;}{\levelnumbers\'01;}\fi-360\li1440}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'03.;}{\levelnumbers\'01;}\fi-360\li1800}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'04.;}{\levelnumbers\'01;}\fi-360\li2160}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'05.;}{\levelnumbers\'01;}\fi-360\li2520}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'06.;}{\levelnumbers\'01;}\fi-360\li2880}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'07.;}{\levelnumbers\'01;}\fi-360\li3240}
+{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'08.;}{\levelnumbers\'01;}\fi-360\li3600}\listid1}
+{\list\listtemplateid2
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}\listid2}
+}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}{\*\generator LibreOffice/6.1.2.1$Linux_X86_64 LibreOffice_project/10$Build-1}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr2018\mo10\dy5\hr19\min21}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720
+\hyphauto0\viewscale150
+{\*\pgdsctbl
+{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}
+{\pgdsc1\pgdscuse451\pgndec\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt1 Endnote;}}
+\formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnar
+{\*\ftnsep\chftnsep}\pgndec\pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af11\langfe1081\dbch\af14\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+Installing TeleGPS software for Mac OS X computers}
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\cf0\kerning1\dbch\af11\langfe1081\dbch\af14\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+The TeleGPS distribution for Mac OS X consists of:}
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 1)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+The TeleGPS application}
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\listtext\pard\plain 2)\tab}\ilvl0\ls1 \li1440\ri0\lin1440\rin0\fi-360\li720\ri0\lin720\rin0\fi-360{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+Current AltOS firmware for TeleGPS products}
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+Install the TeleGPS application by control-clicking the install-macosx script and selecting \u8220\'93Open\u8221\'94 from the menu. This will display a dialog asking if you are sure you want to open it. Select \u8220\'93Open\u8221\'94 from the dialog to execute the script. This will install the software, documentation and firmware in your home Applications/AltOS folder. You can move it afte}{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+r}{\cf0\kerning1\dbch\af10\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+wards if you choose.}
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\cf0\kerning1\dbch\af11\langfe1081\dbch\af16\rtlch \ltrch\loch\fs24\lang1033\loch\f9\hich\af9
+
+\par \pard\plain \s0\ql\widctlpar\hyphpar0\ltrpar\cf0\kerning1\dbch\af11\langfe1081\dbch\af15\afs24\alang1081\loch\f3\fs24\lang1033\sl240\slmult1\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640{\cf0\kerning1\dbch\af10\langfe1081\dbch\af14\rtlch \ltrch\loch\fs24\lang1033\loch\f6\hich\af6
+Thanks for choosing AltusMetrum products!}
+\par }
\ No newline at end of file
import java.util.concurrent.*;
import java.util.*;
import java.text.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPS
extends AltosUIFrame
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSConfig implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSConfigUI
extends AltosUIDialog
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSDisplayThread extends Thread {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSInfo extends AltosUIFlightTab {
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSPreferences
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSState extends AltosUIFlightTab {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_12.*;
-import org.altusmetrum.altosuilib_12.*;
+import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altosuilib_13.*;
public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
package org.altusmetrum.telegps;
import java.awt.event.*;
-import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altoslib_13.*;
public class TeleGPSStatusUpdate implements ActionListener {