comparison Discovery/Src/tCCR.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children 74a8296a2318
comparison
equal deleted inserted replaced
37:ccc45c0e1ea2 38:5f11787b4f42
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 -----------------------------------------------*/
62 void tCCR_fallbackToFixedSetpoint(void);
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
346 void tCCR_fallbackToFixedSetpoint(void)
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 SDiveState *pState;
352
353 if(stateUsed == stateRealGetPointer())
354 pState = stateRealGetPointerWrite();
355 else
356 pState = stateSimGetPointerWrite();
357
358 setpointCbar = pState->diveSettings.setpoint[1].setpoint_cbar;
359 pState->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint;
360
361 actualGasID = pState->lifeData.actualGas.GasIdInSettings;
362 setActualGas_DM(&pState->lifeData,actualGasID,setpointCbar);
363
364 set_warning_fallback();
365 }
366 }