Mercurial > public > ostc4
comparison Discovery/Src/tMenuEditSetpoint.c @ 788:4abfb8a2a435
Define explicit setpoints for low / high / deco. Add an option to delay the switch to SPlow until all decompression has been cleared. (mikeller)
author | heinrichsweikamp |
---|---|
date | Tue, 04 Jul 2023 14:39:06 +0200 |
parents | 46c6d2380d4e |
children | b7cd0c5c8e43 |
comparison
equal
deleted
inserted
replaced
787:aeb72882f30a | 788:4abfb8a2a435 |
---|---|
31 | 31 |
32 #include "check_warning.h" | 32 #include "check_warning.h" |
33 #include "gfx_fonts.h" | 33 #include "gfx_fonts.h" |
34 #include "tMenuEdit.h" | 34 #include "tMenuEdit.h" |
35 #include "unit.h" | 35 #include "unit.h" |
36 #include "tHome.h" | |
36 | 37 |
37 /* Private types -------------------------------------------------------------*/ | 38 /* Private types -------------------------------------------------------------*/ |
38 typedef struct | 39 typedef struct |
39 { | 40 { |
40 uint8_t spID; | 41 uint8_t spID; |
65 unblock_diluent_page(); | 66 unblock_diluent_page(); |
66 } | 67 } |
67 } | 68 } |
68 | 69 |
69 | 70 |
71 static uint8_t OnAction_SP_SetpointActive (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
72 { | |
73 switch (action) { | |
74 case ACTION_BUTTON_ENTER: | |
75 | |
76 return digitContent; | |
77 case ACTION_BUTTON_ENTER_FINAL: | |
78 | |
79 checkAndFixSetpointSettings(); | |
80 | |
81 return UPDATE_AND_EXIT_TO_MENU; | |
82 case ACTION_BUTTON_NEXT: | |
83 case ACTION_BUTTON_BACK: | |
84 editSetpointPage.pSetpointLine[editSetpointPage.spID].note.ub.active = (editSetpointPage.pSetpointLine[editSetpointPage.spID].note.ub.active + 1) % 2; | |
85 | |
86 tMenuEdit_newInput(editId, editSetpointPage.pSetpointLine[editSetpointPage.spID].note.ub.active, 0, 0, 0); | |
87 | |
88 return UNSPECIFIC_RETURN; | |
89 default: | |
90 | |
91 break; | |
92 } | |
93 | |
94 return EXIT_TO_MENU; | |
95 } | |
96 | |
97 | |
98 int printSetpointName(char *text, uint8_t setpointId, SSettings *settings, bool useSmallFont) | |
99 { | |
100 int charsPrinted = 0; | |
101 if (settings->autoSetpoint) { | |
102 switch (setpointId) { | |
103 case SETPOINT_INDEX_AUTO_LOW: | |
104 charsPrinted = snprintf(text, 10, "%s%c%c%s", useSmallFont ? "\016\016" : "", TXT_2BYTE, TXT2BYTE_SetpointLow, useSmallFont ? "\017" : ""); | |
105 | |
106 break; | |
107 case SETPOINT_INDEX_AUTO_HIGH: | |
108 charsPrinted = snprintf(text, 10, "%s%c%c%s", useSmallFont ? "\016\016" : "", TXT_2BYTE, TXT2BYTE_SetpointHigh, useSmallFont ? "\017" : ""); | |
109 | |
110 break; | |
111 case SETPOINT_INDEX_AUTO_DECO: | |
112 charsPrinted = snprintf(text, 10, "%s%c%c%s", useSmallFont ? "\016\016" : "", TXT_2BYTE, TXT2BYTE_SetpointDeco, useSmallFont ? "\017" : ""); | |
113 | |
114 break; | |
115 default: | |
116 | |
117 break; | |
118 } | |
119 } else { | |
120 charsPrinted = snprintf(text, 10, "%d", setpointId); | |
121 } | |
122 | |
123 return charsPrinted; | |
124 } | |
125 | |
126 | |
70 void openEdit_Setpoint(uint8_t line) | 127 void openEdit_Setpoint(uint8_t line) |
71 { | 128 { |
129 SSettings *settings = settingsGetPointer(); | |
130 | |
72 uint8_t useSensorSubMenu = 0; | 131 uint8_t useSensorSubMenu = 0; |
73 char text[20]; | 132 char text[20]; |
74 uint8_t sensorActive[3]; | 133 uint8_t sensorActive[3]; |
75 | 134 |
76 /* dive mode */ | 135 /* dive mode */ |
77 if(actual_menu_content != MENU_SURFACE) | 136 if (actual_menu_content != MENU_SURFACE) { |
78 { | |
79 uint8_t setpointCbar, actualGasID; | 137 uint8_t setpointCbar, actualGasID; |
80 setpointCbar = 100; | 138 setpointCbar = 100; |
81 | 139 |
82 // actualGasID | 140 // actualGasID |
83 if(!isLoopMode(stateUsedWrite->diveSettings.diveMode)) | 141 if(!isLoopMode(stateUsedWrite->diveSettings.diveMode)) |
88 } | 146 } |
89 else | 147 else |
90 actualGasID = stateUsedWrite->lifeData.actualGas.GasIdInSettings; | 148 actualGasID = stateUsedWrite->lifeData.actualGas.GasIdInSettings; |
91 | 149 |
92 // setpointCbar, CCR_Mode and sensor menu | 150 // setpointCbar, CCR_Mode and sensor menu |
93 if((line < 6) && (stateUsedWrite->diveSettings.diveMode != DIVEMODE_PSCR)) /* setpoints inactive in PSCR mode */ | 151 if (line < 6 && stateUsedWrite->diveSettings.diveMode != DIVEMODE_PSCR) { |
94 { | 152 /* setpoints inactive in PSCR mode */ |
153 | |
154 if (settings->autoSetpoint && line > SETPOINT_INDEX_AUTO_DECO) { | |
155 return; | |
156 } | |
157 | |
95 setpointCbar = stateUsedWrite->diveSettings.setpoint[line].setpoint_cbar; | 158 setpointCbar = stateUsedWrite->diveSettings.setpoint[line].setpoint_cbar; |
96 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint; | 159 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_FixedSetpoint; |
97 | 160 } else if (stateUsedWrite->diveSettings.diveMode == DIVEMODE_PSCR && line == 2) { |
98 // BetterSetpoint warning only once | 161 /* menu item not pointing to setpoint selection => use sensor or ppo2 simulation */ |
99 if(actualBetterSetpointId() == line) | 162 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Simulation; |
100 { | 163 } else if (line == 6) { |
101 uint8_t depth; | 164 /* => use sensor */ |
102 depth = stateUsedWrite->diveSettings.setpoint[line].depth_meter; | 165 if(stateUsedWrite->diveSettings.CCR_Mode != CCRMODE_Sensors) |
103 // BetterSetpoint warning only once -> clear active | |
104 for(int i=0; i<=NUM_GASES; i++) | |
105 { | |
106 stateUsedWrite->diveSettings.setpoint[i].note.ub.first = 0; | |
107 if(stateUsedWrite->diveSettings.setpoint[i].depth_meter <= depth) | |
108 stateUsedWrite->diveSettings.setpoint[i].note.ub.active = 0; | |
109 } | |
110 stateUsedWrite->diveSettings.setpoint[line].note.ub.first = 1; | |
111 } | |
112 } | |
113 else /* menu item not pointing to setpoint selection => use sensor or ppo2 simulation */ | |
114 { | |
115 if((stateUsedWrite->diveSettings.diveMode == DIVEMODE_PSCR) && (line == 2)) | |
116 { | 166 { |
117 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Simulation; | 167 /* setpoint_cbar will be written by updateSetpointStateUsed() in main.c loop */ |
168 setpointCbar = 255; | |
169 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Sensors; | |
118 } | 170 } |
119 else /* => use sensor */ | 171 else |
120 { | 172 { |
121 if(stateUsedWrite->diveSettings.CCR_Mode != CCRMODE_Sensors) | 173 useSensorSubMenu = 1; |
122 { | |
123 /* setpoint_cbar will be written by updateSetpointStateUsed() in main.c loop */ | |
124 setpointCbar = 255; | |
125 stateUsedWrite->diveSettings.CCR_Mode = CCRMODE_Sensors; | |
126 } | |
127 else | |
128 { | |
129 useSensorSubMenu = 1; | |
130 } | |
131 } | 174 } |
132 } | 175 } |
133 | 176 |
134 setActualGas_DM(&stateUsedWrite->lifeData,actualGasID,setpointCbar); | 177 setActualGas_DM(&stateUsedWrite->lifeData,actualGasID, setpointCbar); |
135 | 178 |
136 checkSwitchToLoop(); | 179 checkSwitchToLoop(); |
137 | 180 |
138 clear_warning_fallback(); | 181 clear_warning_fallback(); |
139 | 182 |
191 | 234 |
192 setEvent(StMSP_Sensor1, (uint32_t)OnAction_SP_DM_Sensor1); | 235 setEvent(StMSP_Sensor1, (uint32_t)OnAction_SP_DM_Sensor1); |
193 setEvent(StMSP_Sensor2, (uint32_t)OnAction_SP_DM_Sensor2); | 236 setEvent(StMSP_Sensor2, (uint32_t)OnAction_SP_DM_Sensor2); |
194 setEvent(StMSP_Sensor3, (uint32_t)OnAction_SP_DM_Sensor3); | 237 setEvent(StMSP_Sensor3, (uint32_t)OnAction_SP_DM_Sensor3); |
195 } | 238 } |
196 return; | 239 } else { |
197 } | |
198 else | |
199 { | |
200 /* surface mode */ | 240 /* surface mode */ |
201 uint8_t spId, setpoint_cbar, sp_high, depthDeco, first; | 241 uint8_t spId, setpoint_cbar, depthDeco, first; |
202 // uint8_t active, | |
203 char text[70]; | 242 char text[70]; |
204 uint8_t textPointer; | 243 uint8_t textPointer; |
205 uint16_t y_line; | 244 uint16_t y_line; |
206 | 245 |
207 if(line < 6) | 246 if ((!settings->autoSetpoint && line <= 5) || line <= SETPOINT_INDEX_AUTO_DECO) { |
208 { | |
209 set_globalState_Menu_Line(line); | 247 set_globalState_Menu_Line(line); |
210 | 248 |
211 resetMenuEdit(CLUT_MenuPageGasSP); | 249 resetMenuEdit(CLUT_MenuPageGasSP); |
212 | 250 |
213 spId = line; | 251 spId = line; |
214 editSetpointPage.spID = spId; | 252 editSetpointPage.spID = spId; |
215 SSettings *data = settingsGetPointer(); | 253 editSetpointPage.pSetpointLine = settings->setpoint; |
216 editSetpointPage.pSetpointLine = data->setpoint; | |
217 | 254 |
218 setpoint_cbar = editSetpointPage.pSetpointLine[spId].setpoint_cbar; | 255 setpoint_cbar = editSetpointPage.pSetpointLine[spId].setpoint_cbar; |
219 depthDeco = editSetpointPage.pSetpointLine[spId].depth_meter; | 256 depthDeco = editSetpointPage.pSetpointLine[spId].depth_meter; |
220 //active = editSetpointPage.pSetpointLine[spId].note.ub.active; | |
221 first = editSetpointPage.pSetpointLine[spId].note.ub.first; | 257 first = editSetpointPage.pSetpointLine[spId].note.ub.first; |
222 | 258 |
223 sp_high = setpoint_cbar / 100; | 259 uint8_t setpointBar = setpoint_cbar / 100; |
224 | 260 |
225 strcpy(text, "\001" "Setpoint #0 X"); | 261 textPointer = snprintf(text, 20, "\001%c%c ", TXT_2BYTE, TXT2BYTE_Setpoint); |
226 text[11] += spId; | 262 textPointer += printSetpointName(&text[textPointer], line, settings, false); |
227 text[13] = TXT_Setpoint_Edit; | 263 snprintf(&text[textPointer], 20, " %c", TXT_Setpoint_Edit); |
228 write_topline(text); | 264 write_topline(text); |
229 | 265 |
230 | |
231 y_line = ME_Y_LINE_BASE + (line * ME_Y_LINE_STEP); | 266 y_line = ME_Y_LINE_BASE + (line * ME_Y_LINE_STEP); |
232 | 267 |
233 textPointer = 0; | 268 textPointer = snprintf(text, 4, "%c%c", TXT_2BYTE, TXT2BYTE_SetpointShort); |
234 text[textPointer++] = 'S'; | 269 textPointer += printSetpointName(&text[textPointer], line, settings, true); |
235 text[textPointer++] = 'P'; | 270 textPointer += snprintf(&text[textPointer], 60, " %s* \016\016 bar\017", first ? "" : "\177"); |
236 text[textPointer++] = '0' + spId; | 271 |
237 text[textPointer++] = ' '; | 272 if (settings->autoSetpoint && line == SETPOINT_INDEX_AUTO_DECO) { |
238 text[textPointer++] = ' '; | 273 textPointer += snprintf(&text[textPointer], 4, "\n\r"); |
239 | 274 write_label_var(20, 800, y_line, &FontT48, text); |
240 if(first == 0) | 275 |
241 strcpy(&text[textPointer++],"\177"); | 276 write_field_udigit(StMSP_ppo2_setting, 160, 800, y_line, &FontT48, "#.##", (uint32_t)setpointBar, (uint32_t)(setpoint_cbar - (100 * setpointBar)), settings->setpoint[line].note.ub.active, 0); |
242 | 277 |
243 textPointer += snprintf(&text[textPointer], 60,\ | 278 snprintf(text, 60, "\034 \035%c%c\n\r", TXT_2BYTE, TXT2BYTE_Enabled); |
244 "* " | 279 write_label_var(20, 800, y_line + ME_Y_LINE_STEP, &FontT48, text); |
245 " " | 280 write_field_select(StMSP_Active, 160, 800, y_line + ME_Y_LINE_STEP, &FontT48, "#", settings->setpoint[line].note.ub.active, 0, 0, 0); |
246 "\016\016" | 281 } else { |
247 " bar" | 282 textPointer += snprintf(&text[textPointer], 40, "\034 \016\016 \017 \016\016meter\017\035\n\r"); |
248 "\017" | 283 write_label_var(20, 800, y_line, &FontT48, text); |
249 "\034" | 284 write_field_udigit(StMSP_ppo2_setting, 160, 800, y_line, &FontT48, "#.## ###", (uint32_t)setpointBar, (uint32_t)(setpoint_cbar - (100 * setpointBar)), depthDeco, 0); |
250 " " | 285 } |
251 "\016\016" | 286 setEvent(StMSP_ppo2_setting, (uint32_t)OnAction_SP_Setpoint); |
252 " " | 287 setEvent(StMSP_Active, (uint32_t)OnAction_SP_SetpointActive); |
253 "\017" | |
254 " " | |
255 "\016\016" | |
256 "meter" | |
257 "\017" | |
258 "\035" | |
259 "\n\r" | |
260 ); | |
261 write_label_var( 20, 800, y_line, &FontT48, text); | |
262 | |
263 write_field_udigit(StMSP_ppo2_setting, 160, 800, y_line, &FontT48, "#.## ###", (uint32_t)sp_high, (uint32_t)(setpoint_cbar - (100 * sp_high)), depthDeco, 0); | |
264 setEvent(StMSP_ppo2_setting, (uint32_t)OnAction_SP_Setpoint); | |
265 startEdit(); | 288 startEdit(); |
266 } | 289 } else if (line == 5) { |
267 else | 290 settings->delaySetpointLow = !settings->delaySetpointLow; |
268 { | 291 |
269 SSettings *pSettings = settingsGetPointer(); | |
270 | |
271 if(pSettings->autoSetpoint == 0) | |
272 { | |
273 pSettings->autoSetpoint = 1; | |
274 } | |
275 else | |
276 { | |
277 pSettings->autoSetpoint = 0; | |
278 } | |
279 exitMenuEdit_to_Menu_with_Menu_Update_do_not_write_settings_for_this_only(); | 292 exitMenuEdit_to_Menu_with_Menu_Update_do_not_write_settings_for_this_only(); |
293 } else if (line == 6) { | |
294 settings->autoSetpoint = (settings->autoSetpoint + 1) % 2; | |
295 | |
296 checkAndFixSetpointSettings(); | |
297 | |
298 exitMenuEdit_to_Menu_with_Menu_Update_do_not_write_settings_for_this_only(); | |
280 } | 299 } |
281 } | 300 } |
282 } | 301 } |
283 | 302 |
284 static uint8_t OnAction_SP_Setpoint(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | 303 static uint8_t OnAction_SP_Setpoint(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) |
285 { | 304 { |
305 SSettings *settings = settingsGetPointer(); | |
306 | |
286 int8_t digitContentNew; | 307 int8_t digitContentNew; |
287 uint32_t new_integer_part, new_fractional_part, new_cbar, newDepth; | 308 uint32_t new_integer_part, new_fractional_part, new_cbar, newDepth; |
288 | 309 |
289 if(action == ACTION_BUTTON_ENTER) | 310 if(action == ACTION_BUTTON_ENTER) |
290 return digitContent; | 311 return digitContent; |
304 new_integer_part = new_cbar / 100; | 325 new_integer_part = new_cbar / 100; |
305 new_fractional_part = new_cbar - (new_integer_part * 100); | 326 new_fractional_part = new_cbar - (new_integer_part * 100); |
306 | 327 |
307 editSetpointPage.pSetpointLine[editSetpointPage.spID].setpoint_cbar = new_cbar; | 328 editSetpointPage.pSetpointLine[editSetpointPage.spID].setpoint_cbar = new_cbar; |
308 | 329 |
309 if(newDepth > 255) | 330 if (settings->autoSetpoint && editSetpointPage.spID == SETPOINT_INDEX_AUTO_DECO) { |
310 newDepth = 255; | 331 tMenuEdit_newInput(editId, new_integer_part, new_fractional_part, newDepth, 0); |
311 | 332 |
312 editSetpointPage.pSetpointLine[editSetpointPage.spID].depth_meter = newDepth; | 333 checkAndFixSetpointSettings(); |
313 | 334 |
314 return UPDATE_AND_EXIT_TO_MENU; | 335 return EXIT_TO_NEXT_MENU; |
336 } else { | |
337 if (newDepth > 255) { | |
338 newDepth = 255; | |
339 } | |
340 | |
341 editSetpointPage.pSetpointLine[editSetpointPage.spID].depth_meter = newDepth; | |
342 checkAndFixSetpointSettings(); | |
343 | |
344 return UPDATE_AND_EXIT_TO_MENU; | |
345 } | |
315 } | 346 } |
316 | 347 |
317 if(action == ACTION_BUTTON_NEXT) | 348 if(action == ACTION_BUTTON_NEXT) |
318 { | 349 { |
319 digitContentNew = digitContent + 1; | 350 digitContentNew = digitContent + 1; |
338 } | 369 } |
339 | 370 |
340 void openEdit_DiveSelectBetterSetpoint(bool useLastDiluent) | 371 void openEdit_DiveSelectBetterSetpoint(bool useLastDiluent) |
341 { | 372 { |
342 uint8_t spId; | 373 uint8_t spId; |
343 uint8_t depth; | |
344 | 374 |
345 if(stateUsedWrite->diveSettings.diveMode != DIVEMODE_PSCR) /* no setpoints in PSCR mode */ | 375 if(stateUsedWrite->diveSettings.diveMode != DIVEMODE_PSCR) /* no setpoints in PSCR mode */ |
346 { | 376 { |
347 spId = actualBetterSetpointId(); | 377 spId = actualBetterSetpointId(); |
348 | |
349 depth = stateUsedWrite->diveSettings.setpoint[spId].depth_meter; | |
350 | |
351 // BetterSetpoint warning only once -> clear active | |
352 for(int i=0; i<=NUM_GASES; i++) | |
353 { | |
354 stateUsedWrite->diveSettings.setpoint[i].note.ub.first = 0; | |
355 if(stateUsedWrite->diveSettings.setpoint[i].depth_meter <= depth) | |
356 stateUsedWrite->diveSettings.setpoint[i].note.ub.active = 0; | |
357 } | |
358 | |
359 // new setpoint | |
360 stateUsedWrite->diveSettings.setpoint[spId].note.ub.first = 1; | |
361 | 378 |
362 uint8_t gasId; | 379 uint8_t gasId; |
363 if (useLastDiluent) { | 380 if (useLastDiluent) { |
364 gasId = stateUsed->lifeData.lastDiluent_GasIdInSettings; | 381 gasId = stateUsed->lifeData.lastDiluent_GasIdInSettings; |
365 } else { | 382 } else { |
373 | 390 |
374 | 391 |
375 bool findSwitchToSetpoint(void) | 392 bool findSwitchToSetpoint(void) |
376 { | 393 { |
377 uint8_t setpointLowId = getSetpointLowId(); | 394 uint8_t setpointLowId = getSetpointLowId(); |
395 uint8_t setpointLowCBar = 0; | |
396 if (setpointLowId) { | |
397 setpointLowCBar = stateUsed->diveSettings.setpoint[setpointLowId].setpoint_cbar; | |
398 } | |
399 | |
378 uint8_t setpointHighId = getSetpointHighId(); | 400 uint8_t setpointHighId = getSetpointHighId(); |
401 uint8_t setpointHighCBar = 0; | |
402 if (setpointHighId) { | |
403 setpointHighCBar = stateUsed->diveSettings.setpoint[setpointHighId].setpoint_cbar; | |
404 } | |
405 | |
406 uint8_t setpointDecoId = getSetpointDecoId(); | |
407 uint8_t setpointDecoCBar = 0; | |
408 if (setpointDecoId) { | |
409 setpointDecoCBar = stateUsed->diveSettings.setpoint[setpointDecoId].setpoint_cbar; | |
410 } | |
411 uint8_t nextDecoStopDepthM; | |
412 uint16_t nextDecoStopTimeRemainingS; | |
413 const SDecoinfo *decoInfo = getDecoInfo(); | |
414 tHome_findNextStop(decoInfo->output_stop_length_seconds, &nextDecoStopDepthM, &nextDecoStopTimeRemainingS); | |
415 | |
379 uint8_t setpointCurrentCbar = stateUsed->lifeData.actualGas.setPoint_cbar; | 416 uint8_t setpointCurrentCbar = stateUsed->lifeData.actualGas.setPoint_cbar; |
380 if (setpointLowId && setpointCurrentCbar != stateUsed->diveSettings.setpoint[setpointLowId].setpoint_cbar && ((!setpointHighId || setpointCurrentCbar == stateUsed->diveSettings.setpoint[setpointHighId].setpoint_cbar) || stateUsed->lifeData.depth_meter < stateUsed->diveSettings.setpoint[setpointLowId].depth_meter)) { | 417 |
381 switchToSetpointCbar = stateUsed->diveSettings.setpoint[setpointLowId].setpoint_cbar; | 418 // We cycle SPdeco => SPhigh => SPlow => SPdeco when we have a decompression obligation |
382 } else if (setpointHighId && setpointCurrentCbar != stateUsed->diveSettings.setpoint[setpointHighId].setpoint_cbar) { | 419 if (setpointDecoCBar && setpointCurrentCbar != setpointDecoCBar && nextDecoStopDepthM && setpointCurrentCbar != setpointHighCBar) { |
383 switchToSetpointCbar = stateUsed->diveSettings.setpoint[setpointHighId].setpoint_cbar; | 420 switchToSetpointCbar = setpointDecoCBar; |
421 } else if (setpointLowCBar && setpointCurrentCbar != setpointLowCBar && (!setpointHighCBar || setpointCurrentCbar == setpointHighCBar || stateUsed->lifeData.depth_meter < stateUsed->diveSettings.setpoint[setpointLowId].depth_meter)) { | |
422 switchToSetpointCbar = setpointLowCBar; | |
423 } else if (setpointHighCBar && setpointCurrentCbar != setpointHighCBar) { | |
424 switchToSetpointCbar = setpointHighCBar; | |
384 } else { | 425 } else { |
385 // We don't have a setpoint to switch to | 426 // We don't have a setpoint to switch to |
386 switchToSetpointCbar = 0; | 427 switchToSetpointCbar = 0; |
387 | 428 |
388 return false; | 429 return false; |