Mercurial > public > ostc4
annotate Discovery/Src/tHome.c @ 322:31e471d60797 O2_SensorSync
Added start of frame detection for HUD data
In the previous impmenentation the reception and evaluation of 15 byte were used without start detection. As a result sensor data could be stuck in case the frame sequence does not match the structure (e.g. cause by an framing error).
To resolve this in case of an invalid checksumme in combination with a data lost detection a byte based reception is startet to detect the start of a frame using the break between two transmissions.
In addition a babbling idiot protecting has been added because a faulty hardware could have an impact on the OSTC operation (high interrupt load)
author | ideenmodellierer |
---|---|
date | Sun, 30 Jun 2019 21:25:58 +0200 |
parents | 8466c994f3e6 |
children | b111fc4250e9 |
rev | line source |
---|---|
38 | 1 /////////////////////////////////////////////////////////////////////////////// |
2 /// -*- coding: UTF-8 -*- | |
3 /// | |
4 /// \file Discovery/Src/tHome.c | |
5 /// \brief Control for Surface and Dive Templates | |
6 /// \author heinrichs weikamp gmbh | |
7 /// \date 10-November-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 "tHome.h" | |
31 | |
32 #include "data_exchange_main.h" // for dataOutGetPointer() | |
33 #include "gfx_fonts.h" | |
34 #include "t3.h" | |
35 #include "t4_tetris.h" | |
36 #include "t5_gauge.h" | |
37 #include "t6_apnea.h" | |
38 #include "t7.h" | |
39 #include "tDebug.h" | |
40 #include "timer.h" // for timer_Stopwatch_Restart | |
41 #include "tMenu.h" | |
42 #include "tMenuEditGasOC.h" // for openEdit_DiveSelectBetterGas() | |
43 #include "tMenuEditSetpoint.h" // for openEdit_DiveSelectBetterSetpoint() | |
44 #include "simulation.h" | |
45 | |
46 /* Private types -------------------------------------------------------------*/ | |
47 | |
48 /* Exported variables --------------------------------------------------------*/ | |
49 _Bool warning_count_high_time = 0; | |
50 _Bool display_count_high_time = 0; | |
51 | |
52 uint8_t errorsInSettings = 0; | |
53 /* Private variables ---------------------------------------------------------*/ | |
54 static uint8_t warning_toogle_count; | |
55 static uint16_t display_toogle_count; | |
56 static uint16_t tHome_tick_count_cview; | |
57 static uint16_t tHome_tick_count_field; | |
58 | |
59 const uint8_t cv_changelist[6] = {CVIEW_Compass, CVIEW_SummaryOfLeftCorner, CVIEW_Tissues, CVIEW_Profile, CVIEW_EADTime, CVIEW_Gaslist}; | |
60 | |
61 /* Private function prototypes -----------------------------------------------*/ | |
62 | |
63 /* Exported functions --------------------------------------------------------*/ | |
64 | |
65 void set_globalState_tHome(void) | |
66 { | |
67 if(stateUsed->mode == MODE_DIVE) | |
68 set_globalState(StD); | |
69 else | |
70 set_globalState(StS); | |
71 } | |
72 | |
73 | |
74 void tHome_init(void) | |
75 { | |
76 t7_init(); // standard + surface | |
77 t3_init(); // big font | |
78 t4_init(); // game | |
79 t5_init(); // gauge | |
80 t6_init(); // apnea | |
81 } | |
82 | |
83 | |
84 void tHome_init_compass(void) | |
85 { | |
86 init_t7_compass(); | |
87 } | |
88 | |
89 | |
90 void tHome_refresh(void) | |
91 { | |
92 SSettings* pSettings = settingsGetPointer(); | |
93 | |
94 warning_toogle_count++; | |
95 if(warning_toogle_count >= 2* pSettings->warning_blink_dsec) | |
96 warning_toogle_count = 0; | |
97 | |
98 if(warning_toogle_count >= pSettings->warning_blink_dsec) | |
99 warning_count_high_time = 1; | |
100 else | |
101 warning_count_high_time = 0; | |
102 | |
103 | |
104 display_toogle_count++; | |
105 if(display_toogle_count >= 2* pSettings->display_toogle_desc) | |
106 display_toogle_count = 0; | |
107 | |
108 if(display_toogle_count >= pSettings->display_toogle_desc) | |
109 display_count_high_time = 1; | |
110 else | |
111 display_count_high_time = 0; | |
112 | |
113 | |
114 if(pSettings->design == 6) | |
115 t6_refresh(); | |
116 else | |
117 if(pSettings->design == 5) | |
118 t5_refresh(); | |
119 else | |
120 if(pSettings->design == 4) | |
121 t4_refresh(); | |
122 else | |
123 if(pSettings->design == 3) | |
124 t3_refresh(); | |
125 else | |
126 if(pSettings->design == 7) | |
127 t7_refresh(); | |
128 else | |
129 { | |
130 pSettings->design = 7; | |
131 t7_refresh(); | |
132 } | |
133 } | |
134 | |
135 | |
136 void tHome_sleepmode_fun(void) | |
137 { | |
138 t7_refresh_sleepmode_fun(); | |
139 } | |
140 | |
141 | |
142 void tHomeDiveMenuControl(uint8_t sendAction) | |
143 { | |
144 if(sendAction == ACTION_BUTTON_NEXT) | |
145 { | |
146 if(settingsGetPointer()->design == 4) | |
147 return; | |
148 | |
149 if(settingsGetPointer()->design == 3) | |
150 settingsGetPointer()->design = 7; | |
151 | |
152 switch(get_globalState()) | |
153 { | |
154 case StD: | |
155 if(settingsGetPointer()->design == 6) | |
156 { | |
157 if(is_stateUsedSetToSim()) | |
158 set_globalState(StDSIM1); | |
159 else | |
160 set_globalState(StDQUIT); | |
161 break; | |
162 } | |
163 | |
164 if(settingsGetPointer()->design == 5) | |
165 { | |
166 if(t5_getCustomView() == CVIEW_Compass) | |
167 set_globalState(StDBEAR); | |
168 else | |
169 set_globalState(StDRAVG); | |
170 break; | |
171 } | |
172 | |
173 if(stateUsed->warnings.betterGas) | |
174 set_globalState(StDMGAS); | |
175 else | |
176 if(stateUsed->warnings.betterSetpoint) | |
177 set_globalState(StDMSPT); | |
178 else | |
179 set_globalState(StDMENU); | |
180 break; | |
181 | |
182 case StDMGAS: | |
183 if(stateUsed->warnings.betterSetpoint) | |
184 set_globalState(StDMSPT); | |
185 else | |
186 set_globalState(StDMENU); | |
187 break; | |
188 | |
189 case StDMSPT: | |
190 set_globalState(StDMENU); | |
191 break; | |
192 | |
193 case StDMENU: | |
194 if(is_stateUsedSetToSim()) | |
195 set_globalState(StDSIM1); | |
196 else | |
197 set_globalState(StD); | |
198 break; | |
199 | |
200 case StDSIM1: | |
201 set_globalState(StDSIM2); | |
202 break; | |
203 | |
204 case StDSIM2: | |
205 set_globalState(StDSIM3); | |
206 break; | |
207 | |
208 case StDSIM3: | |
209 set_globalState(StDSIM4); | |
210 break; | |
211 | |
212 case StDSIM4: | |
213 set_globalState(StD); | |
214 break; | |
215 | |
216 case StDBEAR: // t5_gauge | |
217 set_globalState(StDRAVG); | |
218 break; | |
219 | |
220 case StDRAVG: // t5_gauge | |
221 if(is_stateUsedSetToSim()) | |
222 set_globalState(StDSIM1); | |
223 else | |
224 set_globalState(StD); | |
225 break; | |
226 | |
227 case StDQUIT: // t6_apnea | |
228 set_globalState(StD); | |
229 break; | |
230 | |
231 default: | |
232 set_globalState(StD); | |
233 } | |
234 } | |
235 | |
236 if(sendAction == ACTION_BUTTON_ENTER) | |
237 { | |
238 if(settingsGetPointer()->design == 4) | |
239 return; | |
240 | |
241 if(settingsGetPointer()->design == 3) | |
242 settingsGetPointer()->design = 7; | |
243 | |
244 switch(get_globalState()) | |
245 { | |
246 case StDMGAS: | |
247 openEdit_DiveSelectBetterGas(); | |
248 set_globalState(StD); | |
249 break; | |
250 case StDMSPT: | |
251 openEdit_DiveSelectBetterSetpoint(); | |
252 set_globalState(StD); | |
253 break; | |
254 | |
255 case StDMENU: | |
256 openMenu_first_page_with_OC_gas_update(); | |
257 break; | |
258 | |
259 case StDSIM1: | |
260 Sim_Quit(); | |
261 break; | |
262 | |
263 case StDSIM2: | |
264 Sim_Ascend(); | |
265 break; | |
266 | |
267 case StDSIM3: | |
268 Sim_Descend(); | |
269 break; | |
270 | |
271 case StDSIM4: | |
272 Sim_Divetime(); | |
273 break; | |
274 | |
275 case StDBEAR: // t5_gauge | |
272
74a8296a2318
cleanup: simplify stateUsed usage
Jan Mulder <jlmulder@xs4all.nl>
parents:
210
diff
changeset
|
276 stateUsedWrite->diveSettings.compassHeading = (uint16_t)stateUsed->lifeData.compass_heading; |
38 | 277 set_globalState(StD); |
278 break; | |
279 | |
280 case StDRAVG: // t5_gauge | |
281 timer_Stopwatch_Restart(); | |
282 set_globalState(StD); | |
283 break; | |
284 | |
285 case StDQUIT: // t6_apnea | |
286 set_globalState(StD); // used to end StDQUIT, is called before everything else because changes are made in the next lines | |
287 if(is_stateUsedSetToSim()) | |
288 Sim_Quit(); | |
289 else | |
290 dataOutGetPointer()->setEndDive = 1; | |
291 break; | |
292 | |
293 default: | |
294 break; | |
295 } | |
296 } | |
297 } | |
298 | |
299 | |
300 void tHome_findNextStop(const uint16_t *list, uint8_t *depthOutMeter, uint16_t *lengthOutSeconds) | |
301 { | |
302 uint8_t ptr = DECOINFO_STRUCT_MAX_STOPS - 1; | |
303 | |
304 while(ptr && !list[ptr]) | |
305 ptr--; | |
306 | |
307 *lengthOutSeconds = list[ptr]; | |
308 if(!(*lengthOutSeconds)) | |
309 { | |
310 *depthOutMeter = 0; | |
311 } | |
312 else | |
313 if(ptr == 0) | |
314 { | |
315 *depthOutMeter = (uint8_t)((stateUsed->diveSettings.last_stop_depth_bar*10.0f) + 0.1f); | |
316 } | |
317 else | |
318 { | |
319 ptr -= 1; | |
320 *depthOutMeter = (uint8_t)(((stateUsed->diveSettings.input_second_to_last_stop_depth_bar + (stateUsed->diveSettings.input_next_stop_increment_depth_bar * ptr))*10.0f) + 0.1f); | |
321 } | |
322 } | |
323 | |
324 | |
325 void tHome_change_field_button_pressed(void) | |
326 { | |
327 tHome_tick_count_field = 0; | |
328 if(settingsGetPointer()->design == 7) | |
329 t7_change_field(); | |
330 } | |
331 | |
332 | |
333 void tHome_change_customview_button_pressed(void) | |
334 { | |
335 tHome_tick_count_cview = 0; | |
336 if(settingsGetPointer()->design == 7) | |
337 t7_change_customview(); | |
338 else | |
339 if(settingsGetPointer()->design == 3) | |
340 t3_change_customview(); | |
341 else | |
342 if(settingsGetPointer()->design == 5) | |
343 t5_change_customview(); | |
344 else | |
345 if(settingsGetPointer()->design == 6) | |
346 t6_change_customview(); | |
347 } | |
348 | |
349 | |
350 void tHome_tick(void) | |
351 { | |
352 uint16_t field = settingsGetPointer()->tX_userselectedLeftLowerCornerTimeout; | |
353 uint16_t cview = settingsGetPointer()->tX_customViewTimeout; | |
354 | |
355 if(field) | |
356 { | |
357 tHome_tick_count_field++; | |
358 if(tHome_tick_count_field > (field * 10)) | |
359 { | |
360 tHome_tick_count_field = 0; | |
361 if(settingsGetPointer()->design == 7) | |
362 { | |
363 t7_set_field_to_primary(); | |
364 } | |
365 } | |
366 } | |
367 | |
368 if(cview) | |
369 { | |
370 tHome_tick_count_cview++; | |
371 if(tHome_tick_count_cview > (cview *10)) | |
372 { | |
373 tHome_tick_count_cview = 0; | |
374 if(settingsGetPointer()->design == 7) | |
375 { | |
376 t7_set_customview_to_primary(); | |
377 } | |
378 } | |
379 } | |
380 } | |
381 | |
382 | |
383 uint32_t tHome_DateCode(RTC_DateTypeDef *dateInput) | |
384 { | |
385 uint32_t answer = 0; | |
386 | |
387 answer = 0; | |
388 answer += (dateInput->Year & 0x7F)<< 9; | |
389 answer += (dateInput->Month & 0x0F)<< 5; | |
390 answer += (dateInput->Date & 0x1F); | |
391 | |
392 return answer; | |
393 } | |
394 | |
395 | |
396 uint8_t tHome_gas_writer(uint8_t oxygen_percentage, uint8_t helium_percentage, char *text) | |
397 { | |
398 if(oxygen_percentage == 100) | |
399 return (uint8_t) snprintf(text,10,"Oxy"); | |
400 else if((oxygen_percentage == 21) && (!helium_percentage)) | |
401 return (uint8_t) snprintf(text,10,"Air"); | |
402 else if(!helium_percentage) | |
403 return (uint8_t) snprintf(text,10,"NX%02i",oxygen_percentage); | |
404 else if((oxygen_percentage + helium_percentage) == 100) | |
405 return (uint8_t) snprintf(text,10,"HX%02i",oxygen_percentage); | |
406 else | |
407 return (uint8_t) snprintf(text,10,"%02i/%02i",oxygen_percentage,helium_percentage); | |
408 } | |
409 | |
410 uint8_t tHome_show_lost_connection_count(GFX_DrawCfgScreen *ScreenToWriteOn) | |
411 { | |
208 | 412 static uint8_t LastKnowRTEState = SPI_RX_STATE_INVALID; |
413 | |
99 | 414 if(!SPI_MIN_ERROR_SHOW) return 0; |
172
c659fda83e44
Minor: Button defaults, release date adjusted, use SPI_SHOW_SYNC_STATS
heinrichsweikamp
parents:
138
diff
changeset
|
415 if(DataEX_lost_connection_count()>=SPI_MIN_ERROR_SHOW && SPI_SHOW_SYNC_STATS){ |
38 | 416 |
99 | 417 char text[64]; |
38 | 418 |
82 | 419 SDataExchangeSlaveToMaster* dataIn=get_dataInPointer(); |
208 | 420 SDataReceiveFromMaster* pDataOut = dataOutGetPointer(); |
82 | 421 |
99 | 422 snprintf(text,32,"spi err:\002 %i/%i",DataEX_lost_connection_count(),get_num_SPI_CALLBACKS()); |
423 Gfx_write_label_var(ScreenToWriteOn, 100,300, 0,&FontT24,CLUT_ButtonSymbols,text); | |
82 | 424 |
104 | 425 // snprintf(text,32,"header:\002%X%X%X%X",dataIn->header.checkCode[0],dataIn->header.checkCode[1],dataIn->header.checkCode[2],dataIn->header.checkCode[3]); |
426 // Gfx_write_label_var(ScreenToWriteOn, 350,550, 0,&FontT24,CLUT_ButtonSymbols,text); | |
82 | 427 |
208 | 428 //snprintf(text,32,"footer:\002%X%X%X%X",dataIn->footer.checkCode[0],dataIn->footer.checkCode[1],dataIn->footer.checkCode[2],dataIn->footer.checkCode[3]); |
429 | |
430 /* data shifted => ignore received data */ | |
431 if((pDataOut->header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_SHIFTED) || (pDataOut->header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_OFFLINE)) | |
432 { | |
433 dataIn->header.checkCode[SPI_HEADER_INDEX_RX_STATE] = LastKnowRTEState; | |
434 } | |
435 else | |
436 { | |
437 LastKnowRTEState =dataIn->header.checkCode[SPI_HEADER_INDEX_RX_STATE]; | |
438 } | |
439 snprintf(text,32,"RX State M|R:\002%X|%X",pDataOut->header.checkCode[SPI_HEADER_INDEX_RX_STATE], dataIn->header.checkCode[SPI_HEADER_INDEX_RX_STATE] ); | |
99 | 440 Gfx_write_label_var(ScreenToWriteOn, 600,800, 0,&FontT24,CLUT_ButtonSymbols,text); |
441 } | |
82 | 442 |
99 | 443 |
444 | |
445 // snprintf(text,32,"cpt:\002%i",get_num_SPI_CALLBACKS()); | |
446 // Gfx_write_label_var(ScreenToWriteOn, 600,800, 90,&FontT24,CLUT_ButtonSymbols,text); | |
82 | 447 |
448 // snprintf(text,10,"i2c:\002%i",get_DataEX_Error_place()); | |
449 // Gfx_write_label_var(ScreenToWriteOn, 600,800, 90,&FontT24,CLUT_ButtonSymbols,text); | |
38 | 450 |
451 return DataEX_lost_connection_count(); | |
452 } |