Mercurial > public > ostc4
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 } |