summaryrefslogtreecommitdiff
path: root/altoslib/AltosEepromRecordMicroPeak2.java
blob: 06ae71f8b3f55186278824ef025abf4525cf8269 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright © 2019 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 class AltosEepromRecordMicroPeak2 extends AltosEepromRecord {
	public static final int	record_length = 2;

	private static final int PA_GROUND_OFFSET = 0;
	private static final int PA_MIN_OFFSET = 4;
	private static final int N_SAMPLES_OFFSET = 8;
	private static final int STARTING_LOG_OFFSET = 10;

	private static final int LOG_ID_MICROPEAK = 0;
	private static final int LOG_ID_MICROKITE = 1;
	private static final int LOG_ID_MICROPEAK2 = 2;

	private int value16(int o) {
		return eeprom.data16(o);
	}

	private int value32(int o) {
		return eeprom.data32(o);
	}

	public int cmd() {
		if (start == 0)
			return AltosLib.AO_LOG_FLIGHT;
		return AltosLib.AO_LOG_SENSOR;
	}

	private int pa_ground() {
		return value32(PA_GROUND_OFFSET);
	}

	private int pa_min() {
		return value32(PA_MIN_OFFSET);
	}

	private int log_id() {
		return value16(N_SAMPLES_OFFSET) >> 12;
	}

	private int n_samples() {
		return value16(N_SAMPLES_OFFSET) & 0xfff;
	}

	private int ticks_per_sample() {
		int log_id = log_id();

		if (log_id == LOG_ID_MICROPEAK)
			return 2;
		if (log_id == LOG_ID_MICROKITE)
			return 200;
		if (log_id == LOG_ID_MICROPEAK2)
			return 10;
		return 1;
	}

	public int tick() {
		if (start <= STARTING_LOG_OFFSET)
			return 0;
		return ((start - STARTING_LOG_OFFSET) / 2) * ticks_per_sample();
	}

	public double ticks_per_sec() {
		int log_id = log_id();

		if (log_id == LOG_ID_MICROPEAK)
			return 1000.0/96.0;
		if (log_id == LOG_ID_MICROKITE)
			return 1000 / 96.0;
		if (log_id == LOG_ID_MICROPEAK2)
			return 100.0;
		return 100.0;
	}

	int mix_in (int high, int low) {
		return  high - (high & 0xffff) + low;
	}

	boolean closer (int target, int a, int b) {
		return Math.abs (target - a) < Math.abs(target - b);
	}

	private int pressure() {
		int cur = value32(PA_GROUND_OFFSET);
		for (int s = STARTING_LOG_OFFSET; s <= start; s += 2) {
			int 	k = value16(s);
			int	same = mix_in(cur, k);
			int	up = mix_in(cur + 0x10000, k);
			int	down = mix_in(cur - 0x10000, k);

			if (closer (cur, same, up)) {
				if (closer (cur, same, down))
					cur = same;
				else
					cur = down;
			} else {
				if (closer (cur, up, down))
					cur = up;
				else
					cur = down;
			}
		}
		return cur;
	}

	public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
		listener.set_tick(tick());
		switch (cmd()) {
		case AltosLib.AO_LOG_FLIGHT:
			int pa_ground = pa_ground();
			int pa_min = pa_min();
			int n_samples = n_samples();
			int log_id = log_id();
			listener.set_state(AltosLib.ao_flight_pad);
			listener.cal_data().set_ground_pressure(pa_ground);
			listener.cal_data().set_ticks_per_sec(ticks_per_sec());
			listener.cal_data().set_boost_tick();
			listener.set_avoid_duplicate_files();
			break;
		case AltosLib.AO_LOG_SENSOR:
			listener.set_state(AltosLib.ao_flight_boost);
			listener.set_pressure(pressure());
			break;
		}
	}

	public int next_start() {
		if (start == 0)
			return STARTING_LOG_OFFSET;
		if (start + 2 >= STARTING_LOG_OFFSET + 2 * n_samples())
			return -1;
		return start + 2;
	}

	public AltosEepromRecord next() {
		int	s = next_start();
		if (s < 0)
			return null;
		return new AltosEepromRecordMicroPeak2(eeprom, s);
	}

	public AltosEepromRecordMicroPeak2(AltosEeprom eeprom, int start) {
		super(eeprom, start, record_length);
	}

	public AltosEepromRecordMicroPeak2(AltosEeprom eeprom) {
		this(eeprom, 0);
	}
}