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;