Mercurial > public > ostc4
annotate Discovery/Src/tCCR.c @ 319:d8e86af78474 fix-version
bugfix: correct packed main version number in dive header
This fixes a rather mysterious bug. Users report that up to 1.3.5 beta,
a correct version number is shown in libdivecomputer based
applications (like in Subsurface, in the extra data tab). Careful
examining the code in both libdivecomputer and the firmware shows
a subtle error in the bit mask and shift operation to pack a full
X.Y.Z.beta version number in 2 bytes (as is available in the
dive header) in the firmware end (as the libdivecomputer code
looks sane, assuming this is the right way to pack things).
Likely, this bug crept in in the conversion from the closed
source Keil period into the open source GCC setup of
the code base. So its impossible to document the exact
history of this problem here.
Further notice that the main version number is only 1 of 3 version
numbers, denoting the full version of the firmware (besides Font
and RTE).
Finally notice that this way of packing is limited to 2^5 bits
(decimal 32), so we could easily build a 1.4.21, but not a
1.4.55.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Wed, 19 Jun 2019 14:31:50 +0200 |
parents | 74a8296a2318 |
children | 31e471d60797 |
rev | line source |
---|---|
38 | 1 /////////////////////////////////////////////////////////////////////////////// |
2 /// -*- coding: UTF-8 -*- | |
3 /// | |
4 /// \file Discovery/Src/tCCR.c | |
5 /// \brief HUD data via optical port | |
6 /// \author Heinrichs Weikamp gmbh | |
7 /// \date 18-Dec-2014 | |
8 /// | |
9 /// \details | |
10 /// | |
11 /// $Id$ | |
12 /////////////////////////////////////////////////////////////////////////////// | |
13 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh | |
14 /// | |
15 /// This program is free software: you can redistribute it and/or modify | |
16 /// it under the terms of the GNU General Public License as published by | |
17 /// the Free Software Foundation, either version 3 of the License, or | |
18 /// (at your option) any later version. | |
19 /// | |
20 /// This program is distributed in the hope that it will be useful, | |
21 /// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 /// GNU General Public License for more details. | |
24 /// | |
25 /// You should have received a copy of the GNU General Public License | |
26 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
27 ////////////////////////////////////////////////////////////////////////////// | |
28 | |
29 /* Includes ------------------------------------------------------------------*/ | |
30 #include <string.h> | |
31 #include "tCCR.h" | |
32 #include "ostc.h" | |
33 #include "data_central.h" | |
34 #include "data_exchange.h" | |
35 #include "check_warning.h" | |
36 | |
37 /* Private types -------------------------------------------------------------*/ | |
38 typedef struct | |
39 { | |
40 uint8_t hud_firmwareVersion; | |
41 bit8_Type status_byte; | |
42 uint16_t sensor_voltage_100uV[3]; | |
43 uint8_t sensor_ppo2_cbar[3]; | |
44 uint8_t temp1; | |
45 uint16_t battery_voltage_mV; | |
46 uint16_t checksum; | |
47 } SIrLink; | |
48 | |
49 /* Private variables ---------------------------------------------------------*/ | |
50 SIrLink receiveHUD[2]; | |
51 uint8_t boolHUDdata = 0; | |
52 uint8_t data_old__lost_connection_to_HUD = 1; | |
53 | |
54 uint8_t receiveHUDraw[16]; | |
55 | |
56 uint8_t StartListeningToUART_HUD = 0; | |
57 uint16_t count = 0; | |
58 | |
59 /* Private variables with external access via get_xxx() function -------------*/ | |
60 | |
61 /* Private function prototypes -----------------------------------------------*/ | |
272
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
62 static void tCCR_fallbackToFixedSetpoint(void); |
38 | 63 |
64 #ifndef USART_IR_HUD | |
65 | |
66 void tCCR_init(void) | |
67 { | |
68 } | |
69 void tCCR_control(void) | |
70 { | |
71 } | |
72 void tCCR_test(void) | |
73 { | |
74 } | |
75 void tCCR_restart(void) | |
76 { | |
77 } | |
78 float get_ppO2Sensor_bar(uint8_t sensor_id) | |
79 { | |
80 } | |
81 float get_sensorVoltage_mV(uint8_t sensor_id) | |
82 { | |
83 } | |
84 float get_HUD_battery_voltage_V(void) | |
85 { | |
86 } | |
87 void tCCR_tick(void) | |
88 { | |
89 } | |
90 | |
91 #else | |
92 /* Exported functions --------------------------------------------------------*/ | |
93 | |
94 float get_ppO2Sensor_bar(uint8_t sensor_id) | |
95 { | |
96 if((sensor_id > 2) || data_old__lost_connection_to_HUD) | |
97 return 0; | |
98 | |
99 return (float)(receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id]) / 100.0f; | |
100 } | |
101 | |
102 float get_sensorVoltage_mV(uint8_t sensor_id) | |
103 { | |
104 if((sensor_id > 2) || data_old__lost_connection_to_HUD) | |
105 return 0; | |
106 | |
107 return (float)(receiveHUD[boolHUDdata].sensor_voltage_100uV[sensor_id]) / 10.0f; | |
108 } | |
109 | |
110 float get_HUD_battery_voltage_V(void) | |
111 { | |
112 if(data_old__lost_connection_to_HUD) | |
113 return 0; | |
114 | |
115 return (float)(receiveHUD[boolHUDdata].battery_voltage_mV) / 1000.0f; | |
116 } | |
117 | |
118 | |
119 void test_HUD_sensor_values_outOfBounds(int8_t * outOfBouds1, int8_t * outOfBouds2, int8_t * outOfBouds3) | |
120 { | |
121 uint8_t sensorNotActiveBinary; | |
122 uint8_t sensorActive[3]; | |
123 | |
124 // test1: user deactivation | |
125 sensorNotActiveBinary = stateUsed->diveSettings.ppo2sensors_deactivated; | |
126 | |
127 for(int i=0;i<3;i++) | |
128 sensorActive[i] = 1; | |
129 | |
130 if(sensorNotActiveBinary) | |
131 { | |
132 if(sensorNotActiveBinary & 1) | |
133 sensorActive[0] = 0; | |
134 | |
135 if(sensorNotActiveBinary & 2) | |
136 sensorActive[1] = 0; | |
137 | |
138 if(sensorNotActiveBinary & 4) | |
139 sensorActive[2] = 0; | |
140 } | |
141 | |
142 // test2: mV of remaining sensors | |
143 for(int i=0;i<3;i++) | |
144 { | |
145 if(sensorActive[i]) | |
146 { | |
147 if( (receiveHUD[boolHUDdata].sensor_voltage_100uV[i] < 80) || | |
148 (receiveHUD[boolHUDdata].sensor_voltage_100uV[i] > 2500)) | |
149 { | |
150 sensorActive[i] = 0; | |
151 switch(i) | |
152 { | |
153 case 0: | |
154 sensorNotActiveBinary |= 1; | |
155 break; | |
156 case 1: | |
157 sensorNotActiveBinary |= 2; | |
158 break; | |
159 case 2: | |
160 sensorNotActiveBinary |= 4; | |
161 break; | |
162 } | |
163 } | |
164 } | |
165 } | |
166 | |
167 *outOfBouds1 = 0; | |
168 *outOfBouds2 = 0; | |
169 *outOfBouds3 = 0; | |
170 | |
171 /* with two, one or no sensor, there is nothing to compare anymore | |
172 */ | |
173 if(sensorNotActiveBinary) | |
174 { | |
175 // set outOfBounds for both tests | |
176 if(!sensorActive[0]) | |
177 *outOfBouds1 = 1; | |
178 | |
179 if(!sensorActive[1]) | |
180 *outOfBouds2 = 1; | |
181 | |
182 if(!sensorActive[2]) | |
183 *outOfBouds3 = 1; | |
184 | |
185 return; | |
186 } | |
187 else | |
188 { | |
189 uint8_t sensor_id_ordered[3]; | |
190 uint8_t difference[2]; | |
191 | |
192 if((receiveHUD[boolHUDdata].sensor_ppo2_cbar[1]) > (receiveHUD[boolHUDdata].sensor_ppo2_cbar[0])) | |
193 { | |
194 sensor_id_ordered[0] = 0; | |
195 sensor_id_ordered[1] = 1; | |
196 } | |
197 else | |
198 { | |
199 sensor_id_ordered[0] = 1; | |
200 sensor_id_ordered[1] = 0; | |
201 } | |
202 if(receiveHUD[boolHUDdata].sensor_ppo2_cbar[2] > receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[1]]) | |
203 { | |
204 sensor_id_ordered[2] = 2; | |
205 } | |
206 else | |
207 { | |
208 sensor_id_ordered[2] = sensor_id_ordered[1]; | |
209 if(receiveHUD[boolHUDdata].sensor_ppo2_cbar[2] > receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[0]]) | |
210 { | |
211 sensor_id_ordered[1] = 2; | |
212 } | |
213 else | |
214 { | |
215 sensor_id_ordered[1] = sensor_id_ordered[0]; | |
216 sensor_id_ordered[0] = 2; | |
217 } | |
218 } | |
219 | |
220 difference[0] = receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[1]]- receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[0]]; | |
221 difference[1] = receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[2]]- receiveHUD[boolHUDdata].sensor_ppo2_cbar[sensor_id_ordered[1]]; | |
222 | |
223 if((difference[0] > difference[1]) && (difference[0] > 15)) | |
224 { | |
225 switch(sensor_id_ordered[0]) | |
226 { | |
227 case 0: | |
228 *outOfBouds1 = 1; | |
229 break; | |
230 case 1: | |
231 *outOfBouds2 = 1; | |
232 break; | |
233 case 2: | |
234 *outOfBouds3 = 1; | |
235 break; | |
236 } | |
237 } | |
238 else | |
239 if((difference[0] < difference[1]) && (difference[1] > 15)) | |
240 { | |
241 switch(sensor_id_ordered[2]) | |
242 { | |
243 case 0: | |
244 *outOfBouds1 = 1; | |
245 break; | |
246 case 1: | |
247 *outOfBouds2 = 1; | |
248 break; | |
249 case 2: | |
250 *outOfBouds3 = 1; | |
251 break; | |
252 } | |
253 } | |
254 } | |
255 } | |
256 | |
257 | |
258 uint8_t get_ppO2SensorWeightedResult_cbar(void) | |
259 { | |
260 int8_t sensorOutOfBound[3]; | |
261 uint16_t result = 0; | |
262 uint8_t count = 0; | |
263 | |
264 test_HUD_sensor_values_outOfBounds(&sensorOutOfBound[0], &sensorOutOfBound[1], &sensorOutOfBound[2]); | |
265 | |
266 for(int i=0;i<3;i++) | |
267 { | |
268 if(!sensorOutOfBound[i]) | |
269 { | |
270 result += receiveHUD[boolHUDdata].sensor_ppo2_cbar[i]; | |
271 count++; | |
272 } | |
273 } | |
274 if(count == 0) // all sensors out of bounds! | |
275 return 0; | |
276 else | |
277 return (uint8_t)(result / count); | |
278 } | |
279 | |
280 | |
281 void tCCR_init(void) | |
282 { | |
283 StartListeningToUART_HUD = 1; | |
284 } | |
285 | |
286 | |
287 /* after 3 seconds without update from HUD | |
288 * data is considered old | |
289 */ | |
290 void tCCR_tick(void) | |
291 { | |
292 if(count < 3 * 10) | |
293 count++; | |
294 else | |
295 { | |
296 data_old__lost_connection_to_HUD = 1; | |
297 if(count < 20 * 10) | |
298 count++; | |
299 else | |
300 tCCR_fallbackToFixedSetpoint(); | |
301 } | |
302 } | |
303 | |
304 | |
305 void tCCR_restart(void) | |
306 { | |
307 HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 15);/* 15*/ | |
308 } | |
309 | |
310 | |
311 void tCCR_control(void) | |
312 { | |
313 if((UartReadyHUD == RESET) && StartListeningToUART_HUD) | |
314 { | |
315 StartListeningToUART_HUD = 0; | |
316 HAL_UART_Receive_IT(&UartIR_HUD_Handle, receiveHUDraw, 15);/* 15*/ | |
317 } | |
318 | |
319 if(UartReadyHUD == SET) | |
320 { | |
321 UartReadyHUD = RESET; | |
322 | |
323 memcpy(&receiveHUD[!boolHUDdata], receiveHUDraw, 11); | |
324 receiveHUD[!boolHUDdata].battery_voltage_mV = receiveHUDraw[11] + (256 * receiveHUDraw[12]); | |
325 receiveHUD[!boolHUDdata].checksum = receiveHUDraw[13] + (256 * receiveHUDraw[14]); | |
326 | |
327 uint16_t checksum = 0; | |
328 | |
329 for(int i=0;i<13;i++) | |
330 { | |
331 checksum += receiveHUDraw[i]; | |
332 } | |
333 if(checksum == receiveHUD[!boolHUDdata].checksum) | |
334 { | |
335 boolHUDdata = !boolHUDdata; | |
336 count = 0; | |
337 data_old__lost_connection_to_HUD = 0; | |
338 } | |
339 StartListeningToUART_HUD = 1; | |
340 } | |
341 } | |
342 | |
343 #endif | |
344 /* Private functions ---------------------------------------------------------*/ | |
345 | |
272
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
346 static void tCCR_fallbackToFixedSetpoint(void) |
38 | 347 { |
348 if((stateUsed->mode == MODE_DIVE) && (stateUsed->diveSettings.diveMode == DIVEMODE_CCR) && (stateUsed->diveSettings.CCR_Mode == CCRMODE_Sensors) && (stateUsed->diveSettings.fallbackOption)) | |
349 { | |
350 uint8_t setpointCbar, actualGasID; | |
351 | |
272
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
352 setpointCbar = stateUsed->diveSettings.setpoint[1].setpoint_cbar; |
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
353 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint; |
38 | 354 |
272
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
355 actualGasID = stateUsed->lifeData.actualGas.GasIdInSettings; |
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
356 setActualGas_DM(&stateUsedWrite->lifeData,actualGasID,setpointCbar); |
38 | 357 |
358 set_warning_fallback(); | |
359 } | |
360 } |