Mercurial > public > hwos_code
comparison src/p2_deco.c @ 650:bc214815deb2
3.19/10.75 release
author | heinrichsweikamp |
---|---|
date | Sun, 28 Aug 2022 13:13:38 +0200 |
parents | 1e695355dfc4 |
children | 75e90cd0c2c3 |
comparison
equal
deleted
inserted
replaced
649:ef2ed7e3a895 | 650:bc214815deb2 |
---|---|
1 // *************************************************************************** | 1 // *************************************************************************** |
2 // p2_deco.c combined next generation V3.12.1 | 2 // p2_deco.c combined next generation V3.19.4 |
3 // | 3 // |
4 // Created on: 12.05.2009 | 4 // Created on: 12.05.2009 |
5 // Author: heinrichs weikamp, contributions by Ralph Lembcke and others | 5 // Author: heinrichs weikamp, contributions by Ralph Lembcke and others |
6 // | 6 // |
7 // *************************************************************************** | 7 // *************************************************************************** |
87 // | 87 // |
88 // ********************************************************************************************************************************* | 88 // ********************************************************************************************************************************* |
89 | 89 |
90 | 90 |
91 #include <math.h> | 91 #include <math.h> |
92 #include <string.h> | |
92 #include "p2_definitions.h" | 93 #include "p2_definitions.h" |
93 #define TEST_MAIN | 94 #define TEST_MAIN |
94 #include "shared_definitions.h" | 95 #include "shared_definitions.h" |
95 #include "configuration.inc" | 96 #include "configuration.inc" |
97 | |
98 | |
99 // work-around for a C18 compiler bug (to avoid a warning been thrown for valid code) | |
100 #define memcpy(a,b,c) memcpy((a),(const void*)(b),(c)) | |
96 | 101 |
97 | 102 |
98 // ********************************************************************************************************************************* | 103 // ********************************************************************************************************************************* |
99 // | 104 // |
100 // C O N S T A N T S D E F I N I T I O N S | 105 // C O N S T A N T S D E F I N I T I O N S |
214 #define PHASE_20_CYCLIC_INIT 0x20 // once-every-cycle initialization of the deco engine | 219 #define PHASE_20_CYCLIC_INIT 0x20 // once-every-cycle initialization of the deco engine |
215 #define PHASE_30_EXTENDED_BOTTOM_TIME 0x30 // calculate extended bottom time | 220 #define PHASE_30_EXTENDED_BOTTOM_TIME 0x30 // calculate extended bottom time |
216 #define PHASE_40_BOTTOM_GAS_NEED 0x40 // calculate gas needs for bottom segment | 221 #define PHASE_40_BOTTOM_GAS_NEED 0x40 // calculate gas needs for bottom segment |
217 #define PHASE_50_NDL_TIME 0x50 // calculate NDL time | 222 #define PHASE_50_NDL_TIME 0x50 // calculate NDL time |
218 #define PHASE_70_ASCENT_OR_RETURN 0x70 // calculate open water ascent or cave return | 223 #define PHASE_70_ASCENT_OR_RETURN 0x70 // calculate open water ascent or cave return |
219 #define PHASE_80_RESULTS 0x80 // results - initialization | 224 #define PHASE_80_RESULTS 0x80 // results - NDL, TTS, TST |
220 #define PHASE_81_RESULTS_STOPS_TABLE 0x81 // results - publish stops table | 225 #define PHASE_81_GAS_NEEDS_PRESSURES 0x81 // results - convert gas needs from volumes to pressures |
221 #define PHASE_82_RESULTS_NDL 0x82 // results - publish data / within NDL | |
222 #define PHASE_83_RESULTS_DECO 0x83 // results - publish data / in deco | |
223 #define PHASE_84_GAS_NEEDS_PRESSURES 0x84 // results - convert gas needs from volumes to pressures | |
224 #define PHASE_85_GAS_NEEDS_CAVE 0x85 // results - tag gas needs as calculated in cave or open water mode | |
225 #define PHASE_90_FINISH 0x90 // finish calculation cycle | 226 #define PHASE_90_FINISH 0x90 // finish calculation cycle |
226 | 227 |
227 | 228 |
228 // gas & diluent - type and availability state | 229 // gas & diluent - type and availability state |
229 // 0x01 // | 0: disabled, 1: first, 2: normal/work, 3: deco | 230 // 0x01 // | 0: disabled, 1: first, 2: normal/work, 3: deco |
278 static void calc_alveolar_pressures(void); // Computes the partial pressures from the gas ratios and many more parameters, | 279 static void calc_alveolar_pressures(void); // Computes the partial pressures from the gas ratios and many more parameters, |
279 // needs either calc_hauptroutine_data_input() be called beforehand or | 280 // needs either calc_hauptroutine_data_input() be called beforehand or |
280 // gas_take_current() or gas_find_best()/gas_take_best() and gas_set_ratios(). | 281 // gas_take_current() or gas_find_best()/gas_take_best() and gas_set_ratios(). |
281 static void calc_tissues(void); // Updates the tissues dependent on the partial pressures of N2 and He. | 282 static void calc_tissues(void); // Updates the tissues dependent on the partial pressures of N2 and He. |
282 static void calc_CNS(void); // Updates the CNS value dependent on the partial pressure of the O2. | 283 static void calc_CNS(void); // Updates the CNS value dependent on the partial pressure of the O2. |
283 static void calc_limit(PARAMETER float GF_current); | 284 static void calc_limit(PARAMETER float GF_parameter); |
284 // Calculates ceiling, current supersaturation factor and some more data. | 285 // Calculates ceiling, current supersaturation factor and some more data. |
285 | 286 |
286 // Functions for TR | 287 // Functions for TR |
287 #ifdef _rx_functions | 288 #ifdef _rx_functions |
288 static void calc_TR_functions(void); // Calculates SAC etc. | 289 static void calc_TR_functions(void); // Calculates SAC etc. |
303 static void calc_NDL_time_tissue(void); // Calculates the remaining NDL time for a given tissue. | 304 static void calc_NDL_time_tissue(void); // Calculates the remaining NDL time for a given tissue. |
304 static unsigned char find_next_stop(void); // Finds the next stop when in a deco ascent. | 305 static unsigned char find_next_stop(void); // Finds the next stop when in a deco ascent. |
305 static void update_deco_table(PARAMETER unsigned char time_increment); | 306 static void update_deco_table(PARAMETER unsigned char time_increment); |
306 // Enters a new stop or extends an existing stop in the deco stops table. | 307 // Enters a new stop or extends an existing stop in the deco stops table. |
307 static void calc_required_volume(void); // Calculates gas volume required for a given depth, time and usage (SAC rate). | 308 static void calc_required_volume(void); // Calculates gas volume required for a given depth, time and usage (SAC rate). |
308 static void convert_volume_to_pressure(void); // Converts gas volumes into pressures and sets respective flags. | 309 static void convert_volume_to_pressure(PARAMETER unsigned char index); |
310 // Converts gas volumes into pressures and sets respective flags. | |
309 | 311 |
310 // Functions for Results Reporting | 312 // Functions for Results Reporting |
311 static void publish_deco_table(void); // Copies the internal deco stops table to the export interface. | 313 static void publish_deco_table(void); // Copies the internal deco stops table to the export interface. |
312 static void convert_cur_CNS_for_display(void); // Converts the current CNS value from float to integer. | 314 static void convert_cur_CNS_for_display(void); // Converts the current CNS value from float to integer. |
313 static void convert_sim_CNS_for_display(void); // Converts the end-of-dive CNS value from float to integer. | 315 static void convert_sim_CNS_for_display(void); // Converts the end-of-dive CNS value from float to integer. |
319 static void load_tmr5(void); // Loads a hardware timer which is used for preemptive scheduling. | 321 static void load_tmr5(void); // Loads a hardware timer which is used for preemptive scheduling. |
320 static void read_tmr5(void); // Reads a hardware timer which is used for preemptive scheduling. | 322 static void read_tmr5(void); // Reads a hardware timer which is used for preemptive scheduling. |
321 static void read_CNS_ab_coefficient(void); // Reads the CNS a and b coefficients from a ROM table. | 323 static void read_CNS_ab_coefficient(void); // Reads the CNS a and b coefficients from a ROM table. |
322 static void read_CNS_c_coefficient(void); // Reads the CNS c coefficient from a ROM table. | 324 static void read_CNS_c_coefficient(void); // Reads the CNS c coefficient from a ROM table. |
323 static void read_Buhlmann_coefficients(void); // Reads the Buhlmann a and b coefficients from a ROM table. | 325 static void read_Buhlmann_coefficients(void); // Reads the Buhlmann a and b coefficients from a ROM table. |
324 static void read_Buhlmann_times(PARAMETER char period); | 326 static void read_Buhlmann_times(PARAMETER unsigned char period); |
325 // Reads pre-computed tissue increment factors from a ROM table. | 327 // Reads pre-computed tissue increment factors from a ROM table. |
326 static void read_Buhlmann_ht(void); // Reads the half-times from a ROM table. | 328 static void read_Buhlmann_ht(void); // Reads the half-times from a ROM table. |
327 static void adopt_Buhlmann_coefficients(void); // Computes average a and b coefficient by the N2/He tissue ratio. | 329 static void adopt_Buhlmann_coefficients(void); // Computes average a and b coefficient by the N2/He tissue ratio. |
328 static void push_tissues_to_vault(void); // Stores the state of the real tissues during simulator runs. | 330 static void push_tissues_to_vault(void); // Stores the state of the real tissues during simulator runs. |
329 static void pull_tissues_from_vault(void); // Restores the state of the real tissues after a simulator run. | 331 static void pull_tissues_from_vault(void); // Restores the state of the real tissues after a simulator run. |
336 // | 338 // |
337 // V A R I A B L E S D E F I N I T I O N S | 339 // V A R I A B L E S D E F I N I T I O N S |
338 // | 340 // |
339 // ********************************************************************************************************************************* | 341 // ********************************************************************************************************************************* |
340 | 342 |
343 | |
344 //---- Bank 13 parameters ----------------------------------------------------- | |
345 #ifndef UNIX | |
346 # pragma udata overlay bank13=0xd00 | |
347 static char C_STACK[256]; // C-code data stack | |
348 # define C_STACK_ADDR C_STACK | |
349 #endif | |
350 | |
351 // 256 byte used, bank is full | |
352 | |
353 | |
354 //---- Bank 7 parameters ----------------------------------------------------- | |
355 #ifndef UNIX | |
356 # pragma udata bank7=0x700 | |
357 #endif | |
358 | |
359 // tissue pressures for the real tissues (128 byte) | |
360 | |
361 static float real_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes || keep order and position of these variables as | |
362 static float real_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes || they are backed-up to & restored from EEPROM! | |
363 | |
364 // delta-pressures for the real tissue pressures (128 byte) | |
365 | |
366 static float real_pres_delta_N2[NUM_COMP]; // 16 floats = 64 bytes | |
367 static float real_pres_delta_He[NUM_COMP]; // 16 floats = 64 bytes | |
368 | |
369 // 256 byte used, bank is full | |
370 | |
371 | |
372 //---- Bank 8 parameters ----------------------------------------------------- | |
373 #ifndef UNIX | |
374 # pragma udata bank8=0x800 | |
375 #endif | |
376 | |
377 // tissue pressures for the simulated tissues (128 byte) | |
378 | |
379 static float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes | |
380 static float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes | |
381 | |
382 // delta-pressures for the simulated tissues (128 byte) | |
383 | |
384 static float sim_pres_delta_N2[NUM_COMP]; // 16 floats = 64 bytes | |
385 static float sim_pres_delta_He[NUM_COMP]; // 16 floats = 64 bytes | |
386 | |
387 // 256 byte used, bank is full | |
388 | |
389 | |
390 //---- Bank 12 parameters ----------------------------------------------------- | |
391 | |
392 #ifndef UNIX | |
393 # pragma udata bank12=0xc00 | |
394 #endif | |
395 | |
396 // vault for backing up real tissue pressures (128 byte) | |
397 | |
398 static float vault_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes | |
399 static float vault_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes | |
400 | |
401 // vault for backing up real delta-pressures (128 byte) | |
402 | |
403 static float vault_pres_delta_N2[NUM_COMP]; // 16 floats = 64 bytes | |
404 static float vault_pres_delta_He[NUM_COMP]; // 16 floats = 64 bytes | |
405 | |
406 // 256 byte used, bank is full | |
407 | |
408 | |
341 //---- Bank 5 parameters ----------------------------------------------------- | 409 //---- Bank 5 parameters ----------------------------------------------------- |
342 #ifndef UNIX | 410 #ifndef UNIX |
343 # pragma udata bank5=0x500 | 411 # pragma udata bank5=0x500 |
344 #endif | 412 #endif |
345 | 413 |
346 // Data that go into the deco data vault (4 byte) | 414 // Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 5, i.e. at address 0x500 ! |
347 | 415 |
348 static float CNS_fraction_real; // || current real CNS (1.00 = 100%) | 416 static volatile unsigned short tmr5_value; // | timer 5 value buffer MUST be at address 0x500 |
417 static volatile unsigned char tmr5_overflow; // | timer 5 overflow flag MUST be at address 0x502 | |
349 | 418 |
350 | 419 |
351 // Environmental and Gas Data (51 byte) | 420 // Environmental and Gas Data (51 byte) |
352 | 421 |
353 static float pres_surface; // absolute pressure at the surface | 422 static float pres_surface; // absolute pressure at the surface |
392 static unsigned char split_N2_He[NUM_COMP]; // used for calculating the desaturation time | 461 static unsigned char split_N2_He[NUM_COMP]; // used for calculating the desaturation time |
393 static unsigned char deco_gas_type[NUM_GAS]; // type and state of the deco gases | 462 static unsigned char deco_gas_type[NUM_GAS]; // type and state of the deco gases |
394 static unsigned char peer_tank[NUM_GAS]; // bit flag vector indicating peer tanks holding same gas | 463 static unsigned char peer_tank[NUM_GAS]; // bit flag vector indicating peer tanks holding same gas |
395 | 464 |
396 | 465 |
397 // real Context: what we are doing now (12 byte) | 466 // real Context: what we are doing now (16 byte) |
398 | 467 |
468 static float CNS_fraction_real; // current real CNS (1.00 = 100%) | |
399 static unsigned short IBCD_tissue_vector; // 16 bit vector to memorize all tissues that experience IBCD | 469 static unsigned short IBCD_tissue_vector; // 16 bit vector to memorize all tissues that experience IBCD |
400 | 470 |
401 static float pres_respiration_sac; // used in SAC calculation: current depth in absolute pressure | 471 static float pres_respiration_sac; // used in SAC calculation: current depth in absolute pressure |
402 static float float_sac; // used in SAC calculation: SAC value in float | 472 static float float_sac; // used in SAC calculation: SAC value in float |
403 static unsigned short max_sac_rate; // used in SAC calculation: threshold for SAC rate attention | 473 static unsigned short max_sac_rate; // used in SAC calculation: threshold for SAC rate attention |
428 static float pres_target; // target pressure for the compartment | 498 static float pres_target; // target pressure for the compartment |
429 static float pres_actual; // current pressure of the compartment | 499 static float pres_actual; // current pressure of the compartment |
430 static unsigned short int_time; // time it takes for the compartment to reach the target pressure | 500 static unsigned short int_time; // time it takes for the compartment to reach the target pressure |
431 | 501 |
432 | 502 |
433 // Gas in Use and Gas Needs (67 byte) | 503 // Gas in Use and Gas Needs (66 byte) |
434 | 504 |
435 static unsigned char start_gas_num; // number of the gas/dil to start with | 505 static unsigned char start_gas_num; // number of the gas/dil to start with |
436 | 506 |
437 static unsigned char sim_gas_last_num; // number of the last used gas | 507 static unsigned char sim_gas_last_num; // number of the last used gas |
438 static unsigned char sim_gas_current_num; // number of the currently used gas | 508 static unsigned char sim_gas_current_num; // number of the currently used gas |
439 static unsigned char sim_gas_current_depth; // change depth of the currently used gas | 509 static unsigned char sim_gas_current_depth; // change depth of the currently used gas |
440 | 510 |
441 static unsigned char sim_gas_best_num; // number of the best gas available | 511 static unsigned char sim_gas_best_num; // number of the best gas available |
442 static unsigned char sim_gas_best_depth; // change depth of the best gas available | 512 static unsigned char sim_gas_best_depth; // change depth of the best gas available |
443 | 513 |
444 static unsigned char gas_needs_gas_index; // index to the gas and tank data arrays | |
445 static float gas_volume_need[NUM_GAS]; // gas volumes required for ascent / cave return in liters | 514 static float gas_volume_need[NUM_GAS]; // gas volumes required for ascent / cave return in liters |
446 static float gas_volume_avail[NUM_GAS]; // gas volumes available for ascent / cave return in liters | 515 static float gas_volume_avail[NUM_GAS]; // gas volumes available for ascent / cave return in liters |
447 static float gas_volume_atten[NUM_GAS]; // attention threshold for gas volumes available | 516 static float gas_volume_atten[NUM_GAS]; // attention threshold for gas volumes available |
448 | 517 |
449 | 518 |
453 static unsigned char gas_needs_time; // duration of the stop, ascent or travel phase | 522 static unsigned char gas_needs_time; // duration of the stop, ascent or travel phase |
454 static unsigned char gas_needs_usage_rate; // gas usage in l/min | 523 static unsigned char gas_needs_usage_rate; // gas usage in l/min |
455 static float gas_needs_volume_due; // computed amount of required gas volume | 524 static float gas_needs_volume_due; // computed amount of required gas volume |
456 | 525 |
457 | 526 |
458 // 243 byte used, 13 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) | 527 // Transfer Values for convert_float_to_int() (6 byte) |
528 | |
529 static float float_value; // input value, float | |
530 static unsigned short int_value; // output value, 16 bit | |
531 | |
532 | |
533 // 251 byte used, 5 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) | |
459 | 534 |
460 | 535 |
461 //---- Bank 6 parameters ----------------------------------------------------- | 536 //---- Bank 6 parameters ----------------------------------------------------- |
462 #ifndef UNIX | 537 #ifndef UNIX |
463 # pragma udata bank6=0x600 | 538 # pragma udata bank6=0x600 |
464 #endif | 539 #endif |
465 | 540 |
466 // Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 6, i.e. at address 0x600 ! | 541 // Modes, Sequencing and Indexing (17 byte) |
467 | |
468 static volatile unsigned short tmr5_value; // | timer 5 value buffer MUST be at address 0x600 | |
469 static volatile unsigned char tmr5_overflow; // | timer 5 overflow flag MUST be at address 0x602 | |
470 | |
471 | |
472 // Modes, Sequencing and Indexing (14 byte) | |
473 | 542 |
474 static unsigned char main_status; // shadow register for char_O_main_status | 543 static unsigned char main_status; // shadow register for char_O_main_status |
475 static unsigned char deco_status; // shadow register for char_O_deco_status | 544 static unsigned char deco_status; // shadow register for char_O_deco_status |
476 static unsigned char deco_info; // shadow register for char_O_deco_info | 545 static unsigned char deco_info; // shadow register for char_O_deco_info |
477 static unsigned char deco_warnings; // shadow register for char_O_deco_warnings | 546 static unsigned char deco_warnings; // shadow register for char_O_deco_warnings |
485 static unsigned char stop_index; // current stop table position | 554 static unsigned char stop_index; // current stop table position |
486 static unsigned char chained_stops; // counter for chained stop entries | 555 static unsigned char chained_stops; // counter for chained stop entries |
487 static unsigned char backtrack_index; // index into the depth backtracking array char_I_backtrack_storage | 556 static unsigned char backtrack_index; // index into the depth backtracking array char_I_backtrack_storage |
488 static unsigned char backtrack_target_depth; // current backtracking target depth | 557 static unsigned char backtrack_target_depth; // current backtracking target depth |
489 static unsigned char backtrack_step_counter; // counter for number of 1/10 minute steps done | 558 static unsigned char backtrack_step_counter; // counter for number of 1/10 minute steps done |
490 | 559 static unsigned char spare; // UNUSED YET, placed here for alignment purpose |
491 | 560 |
492 // Result Values from Calculation Functions (28 byte) | 561 |
562 // Result Values from Calculation Functions (30 byte) | |
493 | 563 |
494 static float ppO2_O2; // ppO2 calculated for breathing pure oxygen in OC mode | 564 static float ppO2_O2; // ppO2 calculated for breathing pure oxygen in OC mode |
495 static float ppO2_OC; // ppO2 calculated for breathing current gas in OC mode | 565 static float ppO2_OC; // ppO2 calculated for breathing current gas in OC mode |
496 static float ppO2_pSCR; // ppO2 calculated for breathing current gas in pSCR mode | 566 static float ppO2_pSCR; // ppO2 calculated for breathing current gas in pSCR mode |
497 | 567 |
517 static float var_He_e; // exposition for current He tissue | 587 static float var_He_e; // exposition for current He tissue |
518 static float var_N2_ht; // half-time for current N2 tissue | 588 static float var_N2_ht; // half-time for current N2 tissue |
519 static float var_He_ht; // half-time for current He tissue | 589 static float var_He_ht; // half-time for current He tissue |
520 | 590 |
521 | 591 |
522 // CNS Coefficients (10 byte) | |
523 | |
524 static float var_cns_gain; // two coefficients approximation, gain | |
525 static float var_cns_offset; // two coefficients approximation, offset | |
526 static unsigned short var_cns_value; // one coefficient approximation, value | |
527 | |
528 | |
529 // Auxiliary Variables for Data Buffering (28 byte) | 592 // Auxiliary Variables for Data Buffering (28 byte) |
530 | 593 |
531 static float N2_equilibrium; // used for N2 tissue graphics scaling | 594 static float N2_equilibrium; // used for N2 tissue graphics scaling |
532 static float temp_tissue; // auxiliary variable to buffer tissue pressures | 595 static float temp_tissue; // auxiliary variable to buffer tissue pressures |
533 static float float_pSCR_factor; // pre-computed factor for pSCR ppO2 drop calculation | 596 static float float_pSCR_factor; // pre-computed factor for pSCR ppO2 drop calculation |
534 static float calc_pres_tissue_N2; // auxiliary variable to buffer tissue N2 pressure | 597 static float calc_pres_tissue_N2; // auxiliary variable to buffer tissue N2 pressure |
535 static float calc_pres_tissue_He; // auxiliary variable to buffer tissue He pressure | 598 static float calc_pres_tissue_He; // auxiliary variable to buffer tissue He pressure |
536 static float pres_tissue; // auxiliary variable to buffer total tissue pressure | 599 static float calc_pres_tissue; // auxiliary variable to buffer total tissue pressure |
537 static float old_pres_respiration; // auxiliary variable to buffer sim_pres_respiration | 600 static float old_pres_respiration; // auxiliary variable to buffer sim_pres_respiration |
538 | 601 |
539 | 602 |
540 // Transfer Values for convert_float_to_int() (6 byte) | 603 // CNS Coefficients (10 byte) |
541 | 604 |
542 static float float_value; // input value, float | 605 static float var_cns_gain; // two coefficients approximation, gain |
543 static unsigned short int_value; // output value, 16 bit | 606 static float var_cns_offset; // two coefficients approximation, offset |
607 static unsigned short var_cns_value; // one coefficient approximation, value | |
608 | |
609 | |
610 // Vault to back-up & restore Tissue related Data (6 byte) | |
611 | |
612 static float vault_CNS_fraction_real; // stores CNS percentage (1.0 = 100%) | |
613 static unsigned char vault_deco_warnings; // stores warnings status | |
614 static unsigned char vault_deco_info; // stores info status | |
615 | |
616 | |
617 // stops table (96 byte) | |
618 | |
619 static unsigned char internal_deco_depth[NUM_STOPS]; // depths of the stops in meters | |
620 static unsigned char internal_deco_time[NUM_STOPS]; // durations of the stops in minutes | |
621 static unsigned char internal_deco_gas[NUM_STOPS]; // gases used on the stops (0 / 1-5) | |
544 | 622 |
545 | 623 |
546 // Performance Profiling (4 byte) | 624 // Performance Profiling (4 byte) |
547 | 625 |
548 static unsigned short profiling_runtime; // performance measurement: runtime of current invocation | 626 static unsigned short profiling_runtime; // performance measurement: runtime of current invocation |
549 static unsigned char profiling_runs; // performance measurement: invocations per deco calculation cycle | 627 static unsigned char profiling_runs; // performance measurement: invocations per deco calculation cycle |
550 static unsigned char profiling_phase; // performance measurement: current calculation phase | 628 static unsigned char profiling_phase; // performance measurement: current calculation phase |
551 | 629 |
552 | 630 |
553 // 7 byte occupied by compiler-placed vars | 631 // Function Parameters placed by the C Compiler (7 byte) |
554 | 632 /* |
555 | 633 static unsigned char period |
556 // 139 byte used, 117 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) | 634 static float parameter |
557 | 635 static unsigned char time_increment |
558 | 636 static unsigned char time_interval |
559 | 637 */ |
560 //---- Bank 12 parameters ----------------------------------------------------- | 638 |
561 #ifndef UNIX | 639 |
562 # pragma udata bank12=0xc00 | 640 // 238 byte used, 18 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) |
563 #endif | 641 |
564 | |
565 // stops table (96 byte) | |
566 | |
567 static unsigned char internal_deco_depth[NUM_STOPS]; // depths of the stops in meters | |
568 static unsigned char internal_deco_time[NUM_STOPS]; // durations of the stops in minutes | |
569 static unsigned char internal_deco_gas[NUM_STOPS]; // gases used on the stops (0 / 1-5) | |
570 | |
571 | |
572 // Vault to back-up & restore Tissue related Data (134 byte) | |
573 | |
574 static float vault_pres_tissue_N2[NUM_COMP]; // stores the nitrogen tissue pressures | |
575 static float vault_pres_tissue_He[NUM_COMP]; // stores the helium tissue pressures | |
576 static float vault_CNS_fraction_real; // stores CNS percentage (1.0 = 100%) | |
577 static unsigned char vault_deco_warnings; // stores warnings status | |
578 static unsigned char vault_deco_info; // stores info status | |
579 | |
580 // 230 byte used, 26 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) | |
581 | |
582 | |
583 //---- Bank 7 parameters ----------------------------------------------------- | |
584 #ifndef UNIX | |
585 # pragma udata bank7=0x700 | |
586 #endif | |
587 | |
588 // Keep order and position of the variables in bank 7 as they are backed-up to & restored from EEPROM | |
589 | |
590 static float real_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes | |
591 static float real_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes | |
592 | |
593 static float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes | |
594 static float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes | |
595 | |
596 // 256 byte used, bank is full | |
597 | |
598 | |
599 //---- Bank 8 parameters ----------------------------------------------------- | |
600 #ifndef UNIX | |
601 # pragma udata overlay bank8=0x800 | |
602 | |
603 static char md_pi_subst[256]; // overlay C-code data stack here, too | |
604 | |
605 # define C_STACK md_pi_subst | |
606 #endif | |
607 | |
608 | |
609 // Back to bank6 for further tmp data | |
610 // Do not delete this assignment, it is needed by the compiler/linker. | |
611 #ifndef UNIX | |
612 # pragma udata bank6 | |
613 #endif | |
614 | 642 |
615 | 643 |
616 // ********************************************************************************************************************************* | 644 // ********************************************************************************************************************************* |
617 // | 645 // |
618 // L O O K - U P T A B L E S | 646 // L O O K - U P T A B L E S |
848 # ifdef _DEBUG | 876 # ifdef _DEBUG |
849 # define RESET_C_STACK fillDataStack(); | 877 # define RESET_C_STACK fillDataStack(); |
850 void fillDataStack(void) | 878 void fillDataStack(void) |
851 { | 879 { |
852 _asm | 880 _asm |
853 LFSR 1,C_STACK | 881 LFSR 1,C_STACK_ADDR |
854 MOVLW 0xCC | 882 MOVLW 0xCC |
855 loop: MOVWF POSTINC1,0 | 883 loop: MOVWF POSTINC1,0 |
856 TSTFSZ FSR1L,0 | 884 TSTFSZ FSR1L,0 |
857 BRA loop | 885 BRA loop |
858 | 886 |
859 LFSR 1,C_STACK | 887 LFSR 1,C_STACK_ADDR |
860 LFSR 2,C_STACK | 888 LFSR 2,C_STACK_ADDR |
861 _endasm | 889 _endasm |
862 } | 890 } |
863 # else | 891 # else |
864 # define RESET_C_STACK \ | 892 # define RESET_C_STACK \ |
865 _asm \ | 893 _asm \ |
866 LFSR 1,C_STACK \ | 894 LFSR 1,C_STACK_ADDR \ |
867 LFSR 2,C_STACK \ | 895 LFSR 2,C_STACK_ADDR \ |
868 _endasm | 896 _endasm |
869 # endif | 897 # endif |
870 #endif | 898 #endif |
871 | 899 |
872 | 900 |
880 // | 908 // |
881 static void load_tmr5(void) | 909 static void load_tmr5(void) |
882 { | 910 { |
883 #ifndef CROSS_COMPILE | 911 #ifndef CROSS_COMPILE |
884 _asm | 912 _asm |
885 movff 0x601,0xF7D // bank-safe load TMR5H from C variable tmr5_value first | 913 movff 0x501,0xF7D // bank-safe load TMR5H from C variable tmr5_value first |
886 movff 0x600,0xF7C // bank-safe load TMR5L from C variable tmr5_value thereafter | 914 movff 0x500,0xF7C // bank-safe load TMR5L from C variable tmr5_value thereafter |
887 bcf 0xFBA,1,0 // clear timer 5 overrun flag (0xFBA = PIR5, bit 1 = TMR5IF) | 915 bcf 0xFBA,1,0 // clear timer 5 overrun flag (0xFBA = PIR5, bit 1 = TMR5IF) |
888 _endasm | 916 _endasm |
889 #else | 917 #else |
890 return; | 918 return; |
891 #endif | 919 #endif |
903 // | 931 // |
904 static void read_tmr5(void) | 932 static void read_tmr5(void) |
905 { | 933 { |
906 #ifndef CROSS_COMPILE | 934 #ifndef CROSS_COMPILE |
907 _asm | 935 _asm |
908 movff 0xF7C,0x600 // copy TMR5L to C variable tmr5_value, low byte first | 936 movff 0xF7C,0x500 // copy TMR5L to C variable tmr5_value, low byte first |
909 movff 0xF7D,0x601 // copy TMR5H to C variable tmr5_value, high byte thereafter | 937 movff 0xF7D,0x501 // copy TMR5H to C variable tmr5_value, high byte thereafter |
910 clrf WREG,0 // clear WREG to 0x00 = no overrun by default | 938 clrf WREG,0 // clear WREG to 0x00 = no overrun by default |
911 btfsc 0xFBA,1,0 // did timer 5 overrun? (0xFBA = PIR5, bit 1 = TMR5IF) | 939 btfsc 0xFBA,1,0 // did timer 5 overrun? (0xFBA = PIR5, bit 1 = TMR5IF) |
912 setf WREG,0 // YES - set WREG to 0xff = overrun detected | 940 setf WREG,0 // YES - set WREG to 0xff = overrun detected |
913 movff WREG,0x602 // copy WREG to C variable tmr5_overflow | 941 movff WREG,0x502 // copy WREG to C variable tmr5_overflow |
914 _endasm | 942 _endasm |
915 #else | 943 #else |
916 return; | 944 return; |
917 #endif | 945 #endif |
918 } | 946 } |
996 ////////////////////////////////////////////////////////////////////////////// | 1024 ////////////////////////////////////////////////////////////////////////////// |
997 // Read Buhlmann increments for compartment ci | 1025 // Read Buhlmann increments for compartment ci |
998 // If period == 0 : 2 sec interval | 1026 // If period == 0 : 2 sec interval |
999 // 1 : 1 min interval | 1027 // 1 : 1 min interval |
1000 // 2 : 10 min interval | 1028 // 2 : 10 min interval |
1001 static void read_Buhlmann_times(PARAMETER char period) | 1029 static void read_Buhlmann_times(PARAMETER unsigned char period) |
1002 { | 1030 { |
1003 #ifndef CROSS_COMPILE | 1031 #ifndef CROSS_COMPILE |
1004 // Note: We don't use far ROM pointer, because handling | 1032 // Note: We don't use far ROM pointer, because handling |
1005 // 24 bit is to complex, hence we have to set the | 1033 // 24 bit is to complex, hence we have to set the |
1006 // UPPER page by hand... | 1034 // UPPER page by hand... |
1092 // | 1120 // |
1093 // Input: var_N2_a, var_N2_b coefficients for N2 | 1121 // Input: var_N2_a, var_N2_b coefficients for N2 |
1094 // var_He_a, var_He_b coefficients for He | 1122 // var_He_a, var_He_b coefficients for He |
1095 // calc_pres_tissue_N2 partial pressure of N2 in tissue | 1123 // calc_pres_tissue_N2 partial pressure of N2 in tissue |
1096 // calc_pres_tissue_He partial pressure of He in tissue | 1124 // calc_pres_tissue_He partial pressure of He in tissue |
1097 // pres_tissue total pressure in tissue | 1125 // calc_pres_tissue total pressure in tissue |
1098 // | 1126 // |
1099 // Output: var_a, var_b coefficients adopted by N2/He ratio | 1127 // Output: var_a, var_b coefficients adopted by N2/He ratio |
1100 // | 1128 // |
1101 static void adopt_Buhlmann_coefficients(void) | 1129 static void adopt_Buhlmann_coefficients(void) |
1102 { | 1130 { |
1103 // adopt a and b coefficients to current N2/He ratio inside the tissue | 1131 // adopt a and b coefficients to current N2/He ratio inside the tissue |
1104 | 1132 |
1105 #ifdef _helium | 1133 #ifdef _helium |
1106 | 1134 |
1107 var_a = (var_N2_a * calc_pres_tissue_N2 + var_He_a * calc_pres_tissue_He) / pres_tissue; | 1135 var_a = (var_N2_a * calc_pres_tissue_N2 + var_He_a * calc_pres_tissue_He) / calc_pres_tissue; |
1108 var_b = (var_N2_b * calc_pres_tissue_N2 + var_He_b * calc_pres_tissue_He) / pres_tissue; | 1136 var_b = (var_N2_b * calc_pres_tissue_N2 + var_He_b * calc_pres_tissue_He) / calc_pres_tissue; |
1109 | 1137 |
1110 #else | 1138 #else |
1111 | 1139 |
1112 var_a = var_N2_a; | 1140 var_a = var_N2_a; |
1113 var_b = var_N2_b; | 1141 var_b = var_N2_b; |
2056 { | 2084 { |
2057 // reset tissue pressures | 2085 // reset tissue pressures |
2058 real_pres_tissue_He[ci] = 0.0; // He | 2086 real_pres_tissue_He[ci] = 0.0; // He |
2059 real_pres_tissue_N2[ci] = N2_equilibrium; // N2 | 2087 real_pres_tissue_N2[ci] = N2_equilibrium; // N2 |
2060 | 2088 |
2089 real_pres_delta_He[ci] = 0.0; // He | |
2090 real_pres_delta_N2[ci] = 0.0; // N2 | |
2091 | |
2061 // reset tissue pressures for scaled tissue graphics | 2092 // reset tissue pressures for scaled tissue graphics |
2062 char_O_tissue_pres_He[ci] = 0; // He | 2093 char_O_tissue_pres_He[ci] = 0; // He |
2063 char_O_tissue_pres_N2[ci] = 10; // N2 | 2094 char_O_tissue_pres_N2[ci] = 10; // N2 |
2064 char_O_tissue_pressure[ci] = 10; // combined | 2095 char_O_tissue_pressure[ci] = 10; // combined |
2065 } | 2096 } |
2159 | 2190 |
2160 // copy master modes to shadow registers | 2191 // copy master modes to shadow registers |
2161 main_status = char_O_main_status; | 2192 main_status = char_O_main_status; |
2162 deco_status = char_O_deco_status; | 2193 deco_status = char_O_deco_status; |
2163 | 2194 |
2164 // clear all command flags on the master mode to signal that the command is read | 2195 // clear all command flags on the master mode to signal that the command is read and in processing |
2165 char_O_deco_status &= ~COMMAND_MASK; | 2196 char_O_deco_status &= ~COMMAND_MASK; |
2166 | 2197 |
2167 // clear the initialization flag on the shadow copy | 2198 // clear the initialization flag on the shadow copy |
2168 deco_status &= ~INITIALIZE; | 2199 deco_status &= ~INITIALIZE; |
2169 | 2200 |
2181 | 2212 |
2182 // copy master modes to shadow registers | 2213 // copy master modes to shadow registers |
2183 main_status = char_O_main_status; | 2214 main_status = char_O_main_status; |
2184 deco_status = char_O_deco_status; | 2215 deco_status = char_O_deco_status; |
2185 | 2216 |
2186 // clear all command flags on the master mode to signal that the command is read | 2217 // clear all command flags on the master mode to signal that the command is read and in processing |
2187 char_O_deco_status &= ~COMMAND_MASK; | 2218 char_O_deco_status &= ~COMMAND_MASK; |
2188 | 2219 |
2189 // set the calculation phase to start with to doing the cyclic initialization | 2220 // set the calculation phase to start with to doing the cyclic initialization |
2190 next_planning_phase = PHASE_20_CYCLIC_INIT; | 2221 next_planning_phase = PHASE_20_CYCLIC_INIT; |
2191 | 2222 |
2323 // deco mode is set | 2354 // deco mode is set |
2324 // AND we are deeper than 7 meters below the deepest deco stop | 2355 // AND we are deeper than 7 meters below the deepest deco stop |
2325 // (7 meters chosen as to be 2 stop depth intervals plus 1 additional meter below) | 2356 // (7 meters chosen as to be 2 stop depth intervals plus 1 additional meter below) |
2326 if ( ( deco_info & DECO_MODE ) > 0 ) | 2357 if ( ( deco_info & DECO_MODE ) > 0 ) |
2327 if ( ( char_depth_real ) > char_O_deco_depth[0] + 7 ) | 2358 if ( ( char_depth_real ) > char_O_deco_depth[0] + 7 ) |
2328 deco_info &= ~DECO_MODE; | 2359 deco_info &= ~DECO_MODE; |
2329 | 2360 |
2330 // Set the deco mode flag if: | 2361 // Set the deco mode flag if: |
2331 // deco mode is not set | 2362 // deco mode is not set |
2332 // AND breathing an OC deco gas (gas type 3) | 2363 // AND breathing an OC deco gas (gas type 3) |
2333 // OR breathing a gas or diluent that officially is disabled (type 0) | 2364 // OR breathing a gas or diluent that officially is disabled (type 0) |
2338 if ( ( deco_info & DECO_MODE ) == 0 ) | 2369 if ( ( deco_info & DECO_MODE ) == 0 ) |
2339 if ( ( char_I_current_gas_type == 3 ) | 2370 if ( ( char_I_current_gas_type == 3 ) |
2340 || ( char_I_current_gas_type == 0 ) | 2371 || ( char_I_current_gas_type == 0 ) |
2341 || ( char_O_deco_depth[0] > 0 ) | 2372 || ( char_O_deco_depth[0] > 0 ) |
2342 ) | 2373 ) |
2343 deco_info |= DECO_MODE; | 2374 deco_info |= DECO_MODE; |
2344 | 2375 |
2345 | 2376 |
2346 //---- Compute ppO2 Warnings ------------------------------------------------------------------ | 2377 //---- Compute ppO2 Warnings ------------------------------------------------------------------ |
2347 | 2378 |
2348 // compute conditional min value | 2379 // compute conditional min value |
2509 // clear deco stops info | 2540 // clear deco stops info |
2510 if( deco_status & CALC_NORM ) deco_info &= ~DECO_STOPS_NORM; | 2541 if( deco_status & CALC_NORM ) deco_info &= ~DECO_STOPS_NORM; |
2511 else deco_info &= ~DECO_STOPS_ALT; | 2542 else deco_info &= ~DECO_STOPS_ALT; |
2512 | 2543 |
2513 // initialize the simulated tissues with the current state of the real tissues | 2544 // initialize the simulated tissues with the current state of the real tissues |
2514 for( i = 0; i < NUM_COMP; i++ ) | 2545 memcpy(sim_pres_tissue_N2, real_pres_tissue_N2, 256); |
2515 { | |
2516 sim_pres_tissue_N2[i] = real_pres_tissue_N2[i]; | |
2517 sim_pres_tissue_He[i] = real_pres_tissue_He[i]; | |
2518 } | |
2519 | 2546 |
2520 // initialize the gas types | 2547 // initialize the gas types |
2521 for( i = 0; i < NUM_GAS; i++ ) | 2548 for( i = 0; i < NUM_GAS; i++ ) |
2522 { | 2549 { |
2523 deco_gas_type[i] = char_I_deco_gas_type[i]; | 2550 deco_gas_type[i] = char_I_deco_gas_type[i]; |
2629 NDL_tissue_start = ( deco_status & CALC_NORM ) ? NDL_tissue_start_norm : NDL_tissue_start_alt; | 2656 NDL_tissue_start = ( deco_status & CALC_NORM ) ? NDL_tissue_start_norm : NDL_tissue_start_alt; |
2630 | 2657 |
2631 // start calculating NDL time with the tissue that had the shortest NDL last time | 2658 // start calculating NDL time with the tissue that had the shortest NDL last time |
2632 NDL_tissue = NDL_tissue_start; | 2659 NDL_tissue = NDL_tissue_start; |
2633 NDL_tissue_lead = NDL_tissue_start; | 2660 NDL_tissue_lead = NDL_tissue_start; |
2634 | |
2635 // initialization for convert_volume_to_pressure() | |
2636 gas_needs_gas_index = 0; | |
2637 | 2661 |
2638 // tag gas needs as not calculated in fTTS mode by default | 2662 // tag gas needs as not calculated in fTTS mode by default |
2639 deco_info &= ~GAS_NEEDS_fTTS; | 2663 deco_info &= ~GAS_NEEDS_fTTS; |
2640 | 2664 |
2641 // shall calculate gas needs? | 2665 // shall calculate gas needs? |
2932 #endif | 2956 #endif |
2933 | 2957 |
2934 // shall calculate gas needs? | 2958 // shall calculate gas needs? |
2935 if( main_status & CALC_VOLUME ) | 2959 if( main_status & CALC_VOLUME ) |
2936 { | 2960 { |
2937 overlay unsigned char index_last_gas = sim_gas_last_num-1; | 2961 overlay unsigned char index_last_gas = sim_gas_last_num - 1; |
2938 overlay unsigned char index_curr_gas = sim_gas_current_num-1; | 2962 overlay unsigned char index_curr_gas = sim_gas_current_num - 1; |
2939 | 2963 |
2940 #ifdef _cave_mode | 2964 #ifdef _cave_mode |
2941 // in cave mode? | 2965 // in cave mode? |
2942 if( main_status & CAVE_MODE ) | 2966 if( main_status & CAVE_MODE ) |
2943 { | 2967 { |
3085 { | 3109 { |
3086 // total time to surface is counted in 1/10 minutes, add 1/10 minute | 3110 // total time to surface is counted in 1/10 minutes, add 1/10 minute |
3087 TTS_time += 1; | 3111 TTS_time += 1; |
3088 } | 3112 } |
3089 | 3113 |
3090 } // overlay | 3114 } |
3091 | 3115 |
3092 // calculate absolute pressure at the current depth | 3116 // calculate absolute pressure at the current depth |
3093 sim_pres_respiration = (float)char_depth_sim * METER_TO_BAR + pres_surface; | 3117 sim_pres_respiration = (float)char_depth_sim * METER_TO_BAR + pres_surface; |
3094 | 3118 |
3095 // compute current ppO2, ppN2 and ppHe | 3119 // compute current ppO2, ppN2 and ppHe |
3115 case PHASE_80_RESULTS: | 3139 case PHASE_80_RESULTS: |
3116 | 3140 |
3117 // convert the CNS value to integer | 3141 // convert the CNS value to integer |
3118 convert_sim_CNS_for_display(); | 3142 convert_sim_CNS_for_display(); |
3119 | 3143 |
3120 // normal or alternative plan? | |
3121 if( deco_status & CALC_NORM ) | |
3122 { | |
3123 // normal plan - export the integer CNS value | |
3124 int_O_CNS_norm = int_sim_CNS_fraction; | |
3125 } | |
3126 else | |
3127 { | |
3128 // alternative plan - export the integer CNS value | |
3129 int_O_CNS_alt = int_sim_CNS_fraction; | |
3130 } | |
3131 | |
3132 // limit total time to surface to display max. and rescale to full minutes | 3144 // limit total time to surface to display max. and rescale to full minutes |
3133 if( TTS_time < 9995 ) TTS_time = (TTS_time + 5) / 10; | 3145 if( TTS_time < 9995 ) TTS_time = (TTS_time + 5) / 10; |
3134 else TTS_time = 999 | INT_FLAG_INVALID; | 3146 else TTS_time = 999 | INT_FLAG_INVALID; |
3135 | 3147 |
3136 // The next calculation phase will | 3148 // limit total stops time to display max. |
3137 // - publish the stops table if in normal plan mode, | 3149 if( TST_time > 999 ) TST_time = 999 | INT_FLAG_INVALID; |
3138 // - proceed with remaining results dependent on if within NDL, or | |
3139 // - in deco | |
3140 if ( deco_status & CALC_NORM ) next_planning_phase = PHASE_81_RESULTS_STOPS_TABLE; | |
3141 else if ( NDL_time ) next_planning_phase = PHASE_82_RESULTS_NDL; | |
3142 else next_planning_phase = PHASE_83_RESULTS_DECO; | |
3143 | |
3144 break; | |
3145 | |
3146 | |
3147 /// | |
3148 //--- Publish Stops Table ----------------------------------------------------------------- | |
3149 // | |
3150 case PHASE_81_RESULTS_STOPS_TABLE: | |
3151 | |
3152 // publish the stops table to the display functions | |
3153 publish_deco_table(); | |
3154 | |
3155 // When entering deco and the ceiling depth becomes > 0 but the | |
3156 // deco calculation reveals no distinct deco stop yet because | |
3157 // the deco obligation will vanish during the ascent, create an | |
3158 // artificial stop to signal that expedite surfacing ("popping | |
3159 // up") is not allowed anymore. | |
3160 if( char_O_deco_depth[0] == 0 ) // simulated ascent reveals no required stops | |
3161 if( int_O_ceiling > 0 ) // real tissues have a ceiling | |
3162 { | |
3163 // set a pro forma stop at the configured last stop depth | |
3164 char_O_deco_depth[0] = char_I_last_stop_depth; | |
3165 | |
3166 // set a stop time of 0 minutes, this will be displayed as "..'" | |
3167 char_O_deco_time[0] = 0; | |
3168 } | |
3169 | |
3170 // The next calculation phase will publish the main results dependent on being | |
3171 // - within NDL, | |
3172 // - in deco. | |
3173 if ( NDL_time ) next_planning_phase = PHASE_82_RESULTS_NDL; | |
3174 else next_planning_phase = PHASE_83_RESULTS_DECO; | |
3175 | |
3176 break; | |
3177 | |
3178 | |
3179 /// | |
3180 //--- Results - within NDL ---------------------------------------------------------------- | |
3181 // | |
3182 case PHASE_82_RESULTS_NDL: | |
3183 | 3150 |
3184 // normal or alternative plan? | 3151 // normal or alternative plan? |
3185 if( deco_status & CALC_NORM ) | 3152 if( deco_status & CALC_NORM ) |
3186 { | 3153 { |
3187 // normal plan - output the NDL and TTS time | 3154 // normal plan |
3188 int_O_NDL_norm = NDL_time; | 3155 |
3189 int_O_TTS_norm = TTS_time; | 3156 // export the integer CNS value |
3190 | 3157 int_O_CNS_norm = int_sim_CNS_fraction; |
3191 // clear the stops time | 3158 |
3192 int_O_TST_norm = 0; | 3159 // publish the stops table to the display functions |
3160 publish_deco_table(); | |
3161 | |
3162 // When in deco and the ceiling depth is > 0 but the deco calculation | |
3163 // reveals no distinct deco stop yet because the deco obligation will | |
3164 // vanish during the ascent, create an artificial stop to signal that | |
3165 // expedite surfacing ("popping up") is not allowed any more. | |
3166 if( char_O_deco_depth[0] == 0 ) // simulated ascent reveals no required stops | |
3167 if( int_O_ceiling > 0 ) // real tissues have a ceiling | |
3168 { | |
3169 // set a pro forma stop at the configured last stop depth | |
3170 char_O_deco_depth[0] = char_I_last_stop_depth; | |
3171 | |
3172 // set a stop time of 0 minutes, this will be displayed as "..'" | |
3173 char_O_deco_time[0] = 0; | |
3174 } | |
3175 | |
3176 // within NDL? | |
3177 if ( NDL_time ) | |
3178 { | |
3179 // YES - output the NDL and TTS time | |
3180 int_O_NDL_norm = NDL_time; | |
3181 int_O_TTS_norm = TTS_time; | |
3182 | |
3183 // clear the stops time | |
3184 int_O_TST_norm = 0; | |
3185 } | |
3186 else | |
3187 { | |
3188 // NO - clear the normal NDL time | |
3189 int_O_NDL_norm = 0; | |
3190 | |
3191 // export the TTS and total stops time | |
3192 int_O_TTS_norm = TTS_time; | |
3193 int_O_TST_norm = TST_time; | |
3194 } | |
3193 } | 3195 } |
3194 else | 3196 else |
3195 { | 3197 { |
3196 // alternative plan - output the NDL time | 3198 // alternative plan |
3197 int_O_NDL_alt = NDL_time; | 3199 |
3198 int_O_TTS_alt = TTS_time; | 3200 // export the integer CNS value |
3199 | 3201 int_O_CNS_alt = int_sim_CNS_fraction; |
3200 // clear the alternative TTS and stops time | 3202 |
3201 int_O_TST_alt = 0 + INT_FLAG_ZERO; | 3203 // within NDL? |
3202 } | 3204 if ( NDL_time ) |
3205 { | |
3206 // YES - output the NDL time | |
3207 int_O_NDL_alt = NDL_time; | |
3208 int_O_TTS_alt = TTS_time; | |
3209 | |
3210 // clear the alternative TTS and stops time | |
3211 int_O_TST_alt = 0 + INT_FLAG_ZERO; | |
3212 } | |
3213 else | |
3214 { | |
3215 // NO - clear the alternative NDL time | |
3216 int_O_NDL_alt = 0; | |
3217 | |
3218 // export the TTS and total stops time | |
3219 int_O_TTS_alt = TTS_time; | |
3220 int_O_TST_alt = TST_time; | |
3221 } | |
3222 } | |
3223 | |
3224 // export deco infos and warnings | |
3225 char_O_deco_info = deco_info; | |
3226 char_O_deco_warnings = deco_warnings; | |
3203 | 3227 |
3204 // The next calculation phase will | 3228 // The next calculation phase will |
3205 // - convert the gas needs from volume to pressure if gas needs calculation is configured | 3229 // - convert the gas needs from volume to pressure if gas needs calculation is configured |
3206 // - else finish the calculation cycle | 3230 // - else finish the calculation cycle |
3207 if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES; | 3231 if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_81_GAS_NEEDS_PRESSURES; |
3208 else next_planning_phase = PHASE_90_FINISH; | |
3209 | |
3210 break; | |
3211 | |
3212 | |
3213 /// | |
3214 //--- Results - in Deco ------------------------------------------------------------------- | |
3215 // | |
3216 case PHASE_83_RESULTS_DECO: | |
3217 | |
3218 // limit total stops time to display max. | |
3219 if( TST_time > 999 ) TST_time = 999 | INT_FLAG_INVALID; | |
3220 | |
3221 | |
3222 // normal or alternative plan? | |
3223 if( deco_status & CALC_NORM ) | |
3224 { | |
3225 // normal plan - clear the normal NDL time | |
3226 int_O_NDL_norm = 0; | |
3227 | |
3228 // export the TTS and total stops time | |
3229 int_O_TTS_norm = TTS_time; | |
3230 int_O_TST_norm = TST_time; | |
3231 } | |
3232 else | |
3233 { | |
3234 // alternative plan - clear the alternative NDL time | |
3235 int_O_NDL_alt = 0; | |
3236 | |
3237 // export the TTS and total stops time | |
3238 int_O_TTS_alt = TTS_time; | |
3239 int_O_TST_alt = TST_time; | |
3240 } | |
3241 | |
3242 // The next calculation phase will | |
3243 // - convert the gas needs from volume to pressure if gas needs calculation is configured | |
3244 // - else finish the calculation cycle | |
3245 if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES; | |
3246 else next_planning_phase = PHASE_90_FINISH; | 3232 else next_planning_phase = PHASE_90_FINISH; |
3247 | 3233 |
3248 break; | 3234 break; |
3249 | 3235 |
3250 | 3236 |
3251 // | 3237 // |
3252 //--- Results - convert Gas Needs Volumes to Pressures ------------------------------------ | 3238 //--- Results - convert Gas Needs Volumes to Pressures ------------------------------------ |
3253 // | 3239 // |
3254 case PHASE_84_GAS_NEEDS_PRESSURES: | 3240 case PHASE_81_GAS_NEEDS_PRESSURES: |
3255 | 3241 |
3256 // convert required volume of the gas pointed to by gas_needs_gas_index | 3242 // step through all gases |
3257 // into the respective pressure and set the flags | 3243 for (i = 0; i < NUM_GAS; i++) |
3258 convert_volume_to_pressure(); | 3244 { |
3259 | 3245 // convert required volume of the gas into the respective pressure and set the flags |
3260 // increment index to address next gas | 3246 convert_volume_to_pressure(i); |
3261 gas_needs_gas_index++; | 3247 } |
3262 | 3248 |
3263 // if all gases have been converted, advance to next calculation phase | |
3264 #ifdef _cave_mode | 3249 #ifdef _cave_mode |
3265 if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_85_GAS_NEEDS_CAVE; | 3250 // tag gas needs as calculated in cave mode or in open water mode |
3266 #else | 3251 if( main_status & CAVE_MODE ) deco_info |= GAS_NEEDS_CAVE; |
3267 if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_90_FINISH; | 3252 else deco_info &= ~GAS_NEEDS_CAVE; |
3268 #endif | 3253 |
3269 | 3254 // export updated deco info |
3270 break; | 3255 char_O_deco_info = deco_info; |
3271 | 3256 #endif |
3272 | |
3273 #ifdef _cave_mode | |
3274 // | |
3275 //--- Results - tag Gas Needs as Cave or Open Water Mode ---------------------------------- | |
3276 // | |
3277 case PHASE_85_GAS_NEEDS_CAVE: | |
3278 | |
3279 // in cave mode? | |
3280 if( main_status & CAVE_MODE ) | |
3281 { | |
3282 // YES - tag gas needs as calculated in cave mode (return along recorded depth profile) | |
3283 deco_info |= GAS_NEEDS_CAVE; | |
3284 } | |
3285 else | |
3286 { | |
3287 // NO - tag gas needs as calculated in open water mode (vertical ascent) | |
3288 deco_info &= ~GAS_NEEDS_CAVE; | |
3289 } | |
3290 | 3257 |
3291 // advance to next calculation phase | 3258 // advance to next calculation phase |
3292 next_planning_phase = PHASE_90_FINISH; | 3259 next_planning_phase = PHASE_90_FINISH; |
3293 | 3260 |
3294 break; | 3261 break; |
3295 #endif | |
3296 | |
3297 | 3262 |
3298 // | 3263 // |
3299 //--- finish Calculation Cycle ------------------------------------------------------------ | 3264 //--- finish Calculation Cycle ------------------------------------------------------------ |
3300 // | 3265 // |
3301 case PHASE_90_FINISH: | 3266 case PHASE_90_FINISH: |
3307 // - if it is not a bailout plan | 3272 // - if it is not a bailout plan |
3308 if( (deco_status & CALC_ALT ) ) | 3273 if( (deco_status & CALC_ALT ) ) |
3309 if( !(int_O_TTS_alt & INT_FLAG_INVALID) ) | 3274 if( !(int_O_TTS_alt & INT_FLAG_INVALID) ) |
3310 if( !(deco_status & BAILOUT_MODE ) ) | 3275 if( !(deco_status & BAILOUT_MODE ) ) |
3311 { | 3276 { |
3312 if( int_O_TTS_alt < int_O_TTS_norm ) deco_info |= DECO_ZONE; | 3277 if ( int_O_TTS_alt < int_O_TTS_norm ) deco_info |= DECO_ZONE; |
3313 if( int_O_TTS_alt > int_O_TTS_norm ) deco_info &= ~DECO_ZONE; | 3278 else if( int_O_TTS_alt > int_O_TTS_norm ) deco_info &= ~DECO_ZONE; |
3314 } | 3279 |
3315 | 3280 // export updated deco info |
3316 // export updated deco infos and warnings | 3281 char_O_deco_info = deco_info; |
3317 char_O_deco_info = deco_info; | 3282 } |
3318 char_O_deco_warnings = deco_warnings; | 3283 |
3319 | 3284 // restore command flag to indicate that the deco calculation cycle has finished |
3320 // restore command flag to indicate that deco calculation cycle has finished | 3285 char_O_deco_status = deco_status; |
3321 char_O_deco_status = deco_status; | |
3322 | 3286 |
3323 // signal end of deco calculation | 3287 // signal end of deco calculation |
3324 next_planning_phase = PHASE_00_DONE; | 3288 next_planning_phase = PHASE_00_DONE; |
3325 | 3289 |
3326 break; | 3290 break; |
3469 // char_O_tissue_pressure[] combined tissue pressures scaled for display purpose (in real tissue context) | 3433 // char_O_tissue_pressure[] combined tissue pressures scaled for display purpose (in real tissue context) |
3470 // | 3434 // |
3471 static void calc_tissues() | 3435 static void calc_tissues() |
3472 { | 3436 { |
3473 overlay unsigned char period; | 3437 overlay unsigned char period; |
3474 overlay float temp_tissue_N2; | 3438 overlay float last_press_tissue; |
3439 overlay float delta_press_N2; | |
3475 | 3440 |
3476 #ifdef _helium | 3441 #ifdef _helium |
3477 overlay float temp_tissue_He; | 3442 overlay float delta_press_He; |
3478 #endif | 3443 #endif |
3479 | |
3480 | 3444 |
3481 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m | 3445 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m |
3482 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m | 3446 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m |
3483 | 3447 |
3484 | 3448 |
3504 period = 1; // - set period length (in cycles) to one | 3468 period = 1; // - set period length (in cycles) to one |
3505 } | 3469 } |
3506 | 3470 |
3507 do | 3471 do |
3508 { | 3472 { |
3509 //---- N2 -------------------------------------------------------- | 3473 if (tissue_increment & TISSUE_SELECTOR) |
3510 | |
3511 temp_tissue = (tissue_increment & TISSUE_SELECTOR) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; | |
3512 | |
3513 temp_tissue = (ppN2 - temp_tissue) * var_N2_e; | |
3514 | |
3515 apply_saturation_factors(); | |
3516 | |
3517 if( tissue_increment & TISSUE_SELECTOR ) | |
3518 { | 3474 { |
3519 temp_tissue_N2 = temp_tissue; | 3475 //---- real N2 -------------------------------------- |
3520 real_pres_tissue_N2[ci] += temp_tissue; | 3476 |
3477 // get the real tissue pressure | |
3478 last_press_tissue = real_pres_tissue_N2[ci]; | |
3479 | |
3480 // calculate the pressure change | |
3481 temp_tissue = (ppN2 - last_press_tissue) * var_N2_e; | |
3482 | |
3483 // apply the saturation / desaturation factor on temp_tissue | |
3484 apply_saturation_factors(); | |
3485 | |
3486 // store the pressure change for IBCD check and tissue graphics | |
3487 delta_press_N2 = temp_tissue; | |
3488 | |
3489 // update the delta accumulator | |
3490 real_pres_delta_N2[ci] += temp_tissue; | |
3491 | |
3492 // update the real tissue pressure | |
3493 real_pres_tissue_N2[ci] += real_pres_delta_N2[ci]; | |
3494 | |
3495 // reduce the delta accumulator | |
3496 real_pres_delta_N2[ci] -= real_pres_tissue_N2[ci] - last_press_tissue; | |
3497 | |
3498 #ifdef _helium | |
3499 //---- real He -------------------------------------- | |
3500 | |
3501 // get the real tissue pressure | |
3502 last_press_tissue = real_pres_tissue_He[ci]; | |
3503 | |
3504 // calculate the pressure change | |
3505 temp_tissue = (ppHe - last_press_tissue) * var_He_e; | |
3506 | |
3507 // apply the saturation / desaturation factor on temp_tissue | |
3508 apply_saturation_factors(); | |
3509 | |
3510 // store the pressure change for IBCD check and tissue graphics | |
3511 delta_press_He = temp_tissue; | |
3512 | |
3513 // update the delta accumulator | |
3514 real_pres_delta_He[ci] += temp_tissue; | |
3515 | |
3516 // update the real tissue pressure | |
3517 real_pres_tissue_He[ci] += real_pres_delta_He[ci]; | |
3518 | |
3519 // reduce the delta accumulator | |
3520 real_pres_delta_He[ci] -= real_pres_tissue_He[ci] - last_press_tissue; | |
3521 #endif | |
3521 } | 3522 } |
3522 else | 3523 else |
3523 { | 3524 { |
3524 sim_pres_tissue_N2[ci] += temp_tissue; | 3525 //---- simulated N2 --------------------------------- |
3526 | |
3527 // get the simulated tissue pressure | |
3528 last_press_tissue = sim_pres_tissue_N2[ci]; | |
3529 | |
3530 // calculate the pressure change | |
3531 temp_tissue = (ppN2 - last_press_tissue) * var_N2_e; | |
3532 | |
3533 // apply the saturation / desaturation factor on temp_tissue | |
3534 apply_saturation_factors(); | |
3535 | |
3536 // update the delta accumulator | |
3537 sim_pres_delta_N2[ci] += temp_tissue; | |
3538 | |
3539 // update the simulated tissue pressure | |
3540 sim_pres_tissue_N2[ci] += sim_pres_delta_N2[ci]; | |
3541 | |
3542 // reduce the delta accumulator | |
3543 sim_pres_delta_N2[ci] -= sim_pres_tissue_N2[ci] - last_press_tissue; | |
3544 | |
3545 #ifdef _helium | |
3546 //---- simulated He --------------------------------- | |
3547 | |
3548 // get the simulated tissue pressure | |
3549 last_press_tissue = sim_pres_tissue_He[ci]; | |
3550 | |
3551 // calculate the pressure change | |
3552 temp_tissue = (ppHe - last_press_tissue) * var_He_e; | |
3553 | |
3554 // apply the saturation / desaturation factor on temp_tissue | |
3555 apply_saturation_factors(); | |
3556 | |
3557 // update the delta accumulator | |
3558 sim_pres_delta_He[ci] += temp_tissue; | |
3559 | |
3560 // update the simulated tissue pressure | |
3561 sim_pres_tissue_He[ci] += sim_pres_delta_He[ci]; | |
3562 | |
3563 // reduce the delta accumulator | |
3564 sim_pres_delta_He[ci] -= sim_pres_tissue_He[ci] - last_press_tissue; | |
3565 #endif | |
3525 } | 3566 } |
3526 | |
3527 #ifdef _helium | |
3528 //---- He -------------------------------------------------------- | |
3529 | |
3530 temp_tissue = (tissue_increment & TISSUE_SELECTOR) ? real_pres_tissue_He[ci] : sim_pres_tissue_He[ci]; | |
3531 | |
3532 temp_tissue = (ppHe - temp_tissue) * var_He_e; | |
3533 | |
3534 apply_saturation_factors(); | |
3535 | |
3536 if( tissue_increment & TISSUE_SELECTOR ) | |
3537 { | |
3538 temp_tissue_He = temp_tissue; | |
3539 real_pres_tissue_He[ci] += temp_tissue; | |
3540 } | |
3541 else | |
3542 { | |
3543 sim_pres_tissue_He[ci] += temp_tissue; | |
3544 } | |
3545 #endif | |
3546 | 3567 |
3547 //---- decrement loop counter and adjust step size --------------- | 3568 //---- decrement loop counter and adjust step size --------------- |
3548 | 3569 |
3549 // decrement loop counter | 3570 // decrement loop counter |
3550 i -= period; | 3571 i -= period; |
3562 // have the computations been done for the "real" tissues? | 3583 // have the computations been done for the "real" tissues? |
3563 if( tissue_increment & TISSUE_SELECTOR ) | 3584 if( tissue_increment & TISSUE_SELECTOR ) |
3564 { | 3585 { |
3565 | 3586 |
3566 #ifdef _helium | 3587 #ifdef _helium |
3567 | |
3568 // net tissue balance | 3588 // net tissue balance |
3569 temp_tissue = temp_tissue_N2 + temp_tissue_He; | 3589 temp_tissue = delta_press_N2 + delta_press_He; |
3570 | |
3571 | 3590 |
3572 // check tissue on-/off-gassing and IBCD with applying a threshold of +/-HYST | 3591 // check tissue on-/off-gassing and IBCD with applying a threshold of +/-HYST |
3573 // | 3592 // |
3574 if ( temp_tissue < -HYST ) // check if the tissue is off-gassing | 3593 if ( temp_tissue < -HYST ) // check if the tissue is off-gassing |
3575 { | 3594 { |
3577 IBCD_tissue_vector &= ~(1 << ci); | 3596 IBCD_tissue_vector &= ~(1 << ci); |
3578 } | 3597 } |
3579 else if ( temp_tissue > +HYST ) // check if the tissue in on-gassing | 3598 else if ( temp_tissue > +HYST ) // check if the tissue in on-gassing |
3580 { | 3599 { |
3581 // check for counter diffusion | 3600 // check for counter diffusion |
3582 if( ((temp_tissue_N2 > 0.0) && (temp_tissue_He < 0.0)) | 3601 if( ((delta_press_N2 > 0.0) && (delta_press_He < 0.0)) |
3583 || ((temp_tissue_N2 < 0.0) && (temp_tissue_He > 0.0)) ) | 3602 || ((delta_press_N2 < 0.0) && (delta_press_He > 0.0)) ) |
3584 { | 3603 { |
3585 // tag tissue as experiencing mentionable IBCD | 3604 // tag tissue as experiencing mentionable IBCD |
3586 IBCD_tissue_vector |= (1 << ci); | 3605 IBCD_tissue_vector |= (1 << ci); |
3587 } | 3606 } |
3588 } | 3607 } |
3589 | |
3590 #endif | 3608 #endif |
3591 | 3609 |
3592 // For N2 tissue pressure display purpose: | 3610 // For N2 tissue pressure display purpose: |
3593 | 3611 |
3594 // basically keep the on-gassing / off-gassing flag from last invocation, but flip | 3612 // basically keep the on-gassing / off-gassing flag from last invocation, but flip |
3595 // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) | 3613 // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) |
3596 char_O_tissue_pres_N2[ci] &= 128; | 3614 char_O_tissue_pres_N2[ci] &= 128; |
3597 if ( temp_tissue_N2 > +HYST ) char_O_tissue_pres_N2[ci] = 128; // set flag for tissue pressure is increasing | 3615 if ( delta_press_N2 > +HYST ) char_O_tissue_pres_N2[ci] = 128; // set flag for tissue pressure is increasing |
3598 else if ( temp_tissue_N2 < -HYST ) char_O_tissue_pres_N2[ci] = 0; // clear flag (-> tissue pressure is decreasing) | 3616 else if ( delta_press_N2 < -HYST ) char_O_tissue_pres_N2[ci] = 0; // clear flag (-> tissue pressure is decreasing) |
3599 | 3617 |
3600 // scale N2 tissue pressure such that the surface steady-state tissue loading | 3618 // scale N2 tissue pressure such that the surface steady-state tissue loading |
3601 // of [0.7902 * (1013 hPa - ppWater)] bar will give a 8, which aligns with | 3619 // of [0.7902 * (1013 hPa - ppWater)] bar will give a 8, which aligns with |
3602 // the 2nd scale line. | 3620 // the 2nd scale line. |
3603 temp_tissue_N2 = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_N2[ci]; | 3621 delta_press_N2 = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_N2[ci]; |
3604 | 3622 |
3605 // limit to 127 to protect the uppermost bit which holds the sat/desat flag | 3623 // limit to 127 to protect the uppermost bit which holds the sat/desat flag |
3606 if (temp_tissue_N2 > 127) temp_tissue_N2 = 127; | 3624 if (delta_press_N2 > 127) delta_press_N2 = 127; |
3607 | 3625 |
3608 // convert to integer and combine with sat/desat flag | 3626 // convert to integer and combine with sat/desat flag |
3609 char_O_tissue_pres_N2[ci] += (unsigned char)temp_tissue_N2; | 3627 char_O_tissue_pres_N2[ci] += (unsigned char)delta_press_N2; |
3610 | 3628 |
3611 #ifdef _helium | 3629 #ifdef _helium |
3612 | 3630 |
3613 // For He tissue pressure display purpose: | 3631 // For He tissue pressure display purpose: |
3614 | 3632 |
3615 // basically keep the on-gassing / off-gassing flag from last invocation, but flip | 3633 // basically keep the on-gassing / off-gassing flag from last invocation, but flip |
3616 // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) | 3634 // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) |
3617 char_O_tissue_pres_He[ci] &= 128; | 3635 char_O_tissue_pres_He[ci] &= 128; |
3618 if ( temp_tissue_He > +HYST ) char_O_tissue_pres_He[ci] = 128; // set flag for tissue pressure is increasing | 3636 if ( delta_press_He > +HYST ) char_O_tissue_pres_He[ci] = 128; // set flag for tissue pressure is increasing |
3619 else if ( temp_tissue_He < -HYST ) char_O_tissue_pres_He[ci] = 0; // clear flag (-> tissue pressure is decreasing) | 3637 else if ( delta_press_He < -HYST ) char_O_tissue_pres_He[ci] = 0; // clear flag (-> tissue pressure is decreasing) |
3620 | 3638 |
3621 // scale He tissue pressure alike it is done for N2. | 3639 // scale He tissue pressure alike it is done for N2. |
3622 // With no He in a tissue, the result will be 0. | 3640 // With no He in a tissue, the result will be 0. |
3623 temp_tissue_He = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_He[ci]; | 3641 delta_press_He = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_He[ci]; |
3624 | 3642 |
3625 // limit to 127 to protect the uppermost bit which holds the sat/desat flag | 3643 // limit to 127 to protect the uppermost bit which holds the sat/desat flag |
3626 if (temp_tissue_He > 127) temp_tissue_He = 127; | 3644 if (delta_press_He > 127) delta_press_He = 127; |
3627 | 3645 |
3628 // convert to integer and combine with sat/desat flag | 3646 // convert to integer and combine with sat/desat flag |
3629 char_O_tissue_pres_He[ci] += (unsigned char)temp_tissue_He; | 3647 char_O_tissue_pres_He[ci] += (unsigned char)delta_press_He; |
3630 | |
3631 | 3648 |
3632 // For combined tissue pressure display purpose: | 3649 // For combined tissue pressure display purpose: |
3633 | 3650 |
3634 // basically keep the on-gassing / off-gassing flag from last invocation, but flip | 3651 // basically keep the on-gassing / off-gassing flag from last invocation, but flip |
3635 // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) | 3652 // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) |
3636 char_O_tissue_pressure[ci] &= 128; | 3653 char_O_tissue_pressure[ci] &= 128; |
3637 if ( temp_tissue > +HYST ) char_O_tissue_pressure[ci] = 128; // set flag for tissue pressure is increasing | 3654 if ( temp_tissue > +HYST ) char_O_tissue_pressure[ci] = 128; // set flag for tissue pressure is increasing |
3638 else if ( temp_tissue < -HYST ) char_O_tissue_pressure[ci] = 0; // clear flag (-> tissue pressure is decreasing) | 3655 else if ( temp_tissue < -HYST ) char_O_tissue_pressure[ci] = 0; // clear flag (-> tissue pressure is decreasing) |
3639 | 3656 |
3640 // add the two scaled pressures. | 3657 // add the two scaled pressures. |
3641 temp_tissue = temp_tissue_N2 + temp_tissue_He; | 3658 temp_tissue = delta_press_N2 + delta_press_He; |
3642 | 3659 |
3643 // limit to 127 to protect the uppermost bit which holds the sat/desat flag | 3660 // limit to 127 to protect the uppermost bit which holds the sat/desat flag |
3644 if (temp_tissue > 127) temp_tissue = 127; | 3661 if (temp_tissue > 127) temp_tissue = 127; |
3645 | 3662 |
3646 // convert to integer and combine with sat/desat flag | 3663 // convert to integer and combine with sat/desat flag |
3730 calc_pres_tissue_N2 = sim_pres_tissue_N2[ci]; | 3747 calc_pres_tissue_N2 = sim_pres_tissue_N2[ci]; |
3731 calc_pres_tissue_He = sim_pres_tissue_He[ci]; | 3748 calc_pres_tissue_He = sim_pres_tissue_He[ci]; |
3732 } | 3749 } |
3733 | 3750 |
3734 // overall tissue pressure | 3751 // overall tissue pressure |
3735 pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; | 3752 calc_pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; |
3736 | 3753 |
3737 #else | 3754 #else |
3738 | 3755 |
3739 // get the tissue pressure | 3756 // get the tissue pressure |
3740 pres_tissue = ( tissue_increment & TISSUE_SELECTOR ) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; | 3757 calc_pres_tissue = ( tissue_increment & TISSUE_SELECTOR ) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; |
3741 | 3758 |
3742 #endif | 3759 #endif |
3743 | 3760 |
3744 // adopt a and b coefficients to current N2/He ratio inside the tissue | 3761 // adopt a and b coefficients to current N2/He ratio inside the tissue |
3745 adopt_Buhlmann_coefficients(); | 3762 adopt_Buhlmann_coefficients(); |
3751 overlay float supersat; | 3768 overlay float supersat; |
3752 overlay float baseline_threshold; | 3769 overlay float baseline_threshold; |
3753 | 3770 |
3754 | 3771 |
3755 // check if tissue is in supersaturation | 3772 // check if tissue is in supersaturation |
3756 if( pres_tissue > real_pres_respiration ) | 3773 if( calc_pres_tissue > real_pres_respiration ) |
3757 { | 3774 { |
3758 // calculate maximum allowed tissue pressure at current ambient pressure | 3775 // calculate maximum allowed tissue pressure at current ambient pressure |
3759 pres_tissue_max = real_pres_respiration / var_b + var_a; | 3776 pres_tissue_max = real_pres_respiration / var_b + var_a; |
3760 | 3777 |
3761 // calculate current supersaturation value (1.0 = 100%) of this tissue according to straight Buhlmann | 3778 // calculate current supersaturation value (1.0 = 100%) of this tissue according to straight Buhlmann |
3762 supersat = ( pres_tissue - real_pres_respiration ) | 3779 supersat = ( calc_pres_tissue - real_pres_respiration ) |
3763 / ( pres_tissue_max - real_pres_respiration ); | 3780 / ( pres_tissue_max - real_pres_respiration ); |
3764 | 3781 |
3765 // calculate supersaturation value for display purpose: 1.35 = 135% = 86 pixel | 3782 // calculate supersaturation value for display purpose: 1.35 = 135% = 86 pixel |
3766 if( supersat <= 1.35 ) char_O_tissue_saturation[ci] = (unsigned char)(supersat * 64); | 3783 if( supersat <= 1.35 ) char_O_tissue_saturation[ci] = (unsigned char)(supersat * 64); |
3767 else char_O_tissue_saturation[ci] = 86; | 3784 else char_O_tissue_saturation[ci] = 86; |
3768 | 3785 |
3812 | 3829 |
3813 // calculate the minimum ambient pressure that the tissue can withstand | 3830 // calculate the minimum ambient pressure that the tissue can withstand |
3814 if( char_I_model == 0 ) | 3831 if( char_I_model == 0 ) |
3815 { | 3832 { |
3816 // straight Buhlmann | 3833 // straight Buhlmann |
3817 pres_ambient_min_tissue = (pres_tissue - var_a) * var_b; | 3834 pres_ambient_min_tissue = (calc_pres_tissue - var_a) * var_b; |
3818 } | 3835 } |
3819 else | 3836 else |
3820 { | 3837 { |
3821 // Buhlmann with Eric Baker's varying gradient factor correction | 3838 // Buhlmann with Eric Baker's varying gradient factor correction |
3822 // note: this equation [1] is the inverse of equation [2] | 3839 // note: this equation [1] is the inverse of equation [2] |
3823 pres_ambient_min_tissue = ( pres_tissue - (var_a * GF_parameter) ) | 3840 pres_ambient_min_tissue = ( calc_pres_tissue - (var_a * GF_parameter) ) |
3824 / ( 1.0 - GF_parameter + (GF_parameter / var_b ) ); | 3841 / ( 1.0 - GF_parameter + (GF_parameter / var_b ) ); |
3825 } | 3842 } |
3826 | 3843 |
3827 // check if this tissue requires a higher ambient pressure than was found to be needed up to now | 3844 // check if this tissue requires a higher ambient pressure than was found to be needed up to now |
3828 if( pres_ambient_min_tissue > pres_ambient_min_overall ) | 3845 if( pres_ambient_min_tissue > pres_ambient_min_overall ) |
3901 calc_pres_tissue_He = last_pres_tissue_He = sim_pres_tissue_He[ci]; | 3918 calc_pres_tissue_He = last_pres_tissue_He = sim_pres_tissue_He[ci]; |
3902 | 3919 |
3903 #else | 3920 #else |
3904 | 3921 |
3905 // get the current simulated tissue pressure | 3922 // get the current simulated tissue pressure |
3906 pres_tissue = last_pres_tissue = sim_pres_tissue_N2[ci]; | 3923 calc_pres_tissue = last_pres_tissue = sim_pres_tissue_N2[ci]; |
3907 | 3924 |
3908 // set the a and b coefficients | 3925 // set the a and b coefficients |
3909 adopt_Buhlmann_coefficients(); | 3926 adopt_Buhlmann_coefficients(); |
3910 | 3927 |
3911 #endif | 3928 #endif |
3915 { | 3932 { |
3916 | 3933 |
3917 #ifdef _helium | 3934 #ifdef _helium |
3918 | 3935 |
3919 // calculate the total tissue pressure | 3936 // calculate the total tissue pressure |
3920 pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; | 3937 calc_pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; |
3921 | 3938 |
3922 // adopt a and b coefficients to current N2/He ratio inside the tissue | 3939 // adopt a and b coefficients to current N2/He ratio inside the tissue |
3923 adopt_Buhlmann_coefficients(); | 3940 adopt_Buhlmann_coefficients(); |
3924 | 3941 |
3925 #endif | 3942 #endif |
3936 // straight Buhlmann | 3953 // straight Buhlmann |
3937 pres_limit = pres_surface / var_b + var_a; | 3954 pres_limit = pres_surface / var_b + var_a; |
3938 } | 3955 } |
3939 | 3956 |
3940 // is the tissue pressure higher than the maximum tissue pressure allowed? | 3957 // is the tissue pressure higher than the maximum tissue pressure allowed? |
3941 if( pres_tissue > pres_limit) | 3958 if( calc_pres_tissue > pres_limit) |
3942 { | 3959 { |
3943 // YES - tissue is outside NDL | 3960 // YES - tissue is outside NDL |
3944 | 3961 |
3945 // was the tissue outside NDL right from the start? | 3962 // was the tissue outside NDL right from the start? |
3946 if( NDL_time_tissue == 0 ) | 3963 if( NDL_time_tissue == 0 ) |
3975 calc_pres_tissue_He = last_pres_tissue_He; | 3992 calc_pres_tissue_He = last_pres_tissue_He; |
3976 | 3993 |
3977 #else | 3994 #else |
3978 | 3995 |
3979 // go back to last pressure | 3996 // go back to last pressure |
3980 pres_tissue = last_pres_tissue; | 3997 calc_pres_tissue = last_pres_tissue; |
3981 | 3998 |
3982 #endif | 3999 #endif |
3983 | 4000 |
3984 // reduce step size to 1 minute | 4001 // reduce step size to 1 minute |
3985 step_size = 1; | 4002 step_size = 1; |
4027 last_pres_tissue_He = calc_pres_tissue_He; | 4044 last_pres_tissue_He = calc_pres_tissue_He; |
4028 | 4045 |
4029 #else | 4046 #else |
4030 | 4047 |
4031 // back-up current tissue pressure | 4048 // back-up current tissue pressure |
4032 last_pres_tissue = pres_tissue; | 4049 last_pres_tissue = calc_pres_tissue; |
4033 | 4050 |
4034 #endif | 4051 #endif |
4035 | 4052 |
4036 // step forward NDL time of current tissue | 4053 // step forward NDL time of current tissue |
4037 NDL_time_tissue += step_size; | 4054 NDL_time_tissue += step_size; |
4049 calc_pres_tissue_He += temp_tissue; // add pressure delta to tissue | 4066 calc_pres_tissue_He += temp_tissue; // add pressure delta to tissue |
4050 | 4067 |
4051 #else | 4068 #else |
4052 | 4069 |
4053 // step forward tissue pressure | 4070 // step forward tissue pressure |
4054 temp_tissue = (ppN2 - pres_tissue ) * var_N2_e; // pressure delta breathed - tissue | 4071 temp_tissue = (ppN2 - calc_pres_tissue ) * var_N2_e; // pressure delta breathed - tissue |
4055 apply_saturation_factors(); // apply safety factor | 4072 apply_saturation_factors(); // apply safety factor |
4056 pres_tissue += temp_tissue; // add pressure delta to tissue | 4073 calc_pres_tissue += temp_tissue; // add pressure delta to tissue |
4057 | 4074 |
4058 #endif | 4075 #endif |
4059 | 4076 |
4060 } | 4077 } |
4061 } | 4078 } |
5110 ////////////////////////////////////////////////////////////////////////////// | 5127 ////////////////////////////////////////////////////////////////////////////// |
5111 // convert_volume_to_pressure | 5128 // convert_volume_to_pressure |
5112 // | 5129 // |
5113 // Converts gas volumes into pressures and sets respective flags | 5130 // Converts gas volumes into pressures and sets respective flags |
5114 // | 5131 // |
5115 // Input: gas_needs_gas_index index of the gas to convert (0-4) | 5132 // Input: index index of the gas to convert (0-4) |
5116 // gas_volume_need[] needed gas volume in liters | 5133 // gas_volume_need[] needed gas volume in liters |
5117 // char_I_gas_avail_pres[] available gas volume in bar | 5134 // char_I_gas_avail_pres[] available gas volume in bar |
5118 // char_I_gas_avail_size[] size of the tanks in liters | 5135 // char_I_gas_avail_size[] size of the tanks in liters |
5119 // char_I_pressure_gas[] gas configured on reading 1/2 (TR only) | 5136 // char_I_pressure_gas[] gas configured on reading 1/2 (TR only) |
5120 // | 5137 // |
5121 // Output: int_O_gas_need_vol[] required gas amount in liters | 5138 // Output: int_O_gas_need_vol[] required gas amount in liters |
5122 // int_O_gas_need_pres[] required gas amount in bar, including flags | 5139 // int_O_gas_need_pres[] required gas amount in bar, including flags |
5123 // int_O_pressure_need[] required gas amount for reading 1/2 (TR only) | 5140 // int_O_pressure_need[] required gas amount for reading 1/2 (TR only) |
5124 // | 5141 // |
5125 static void convert_volume_to_pressure(void) | 5142 static void convert_volume_to_pressure(PARAMETER unsigned char index) |
5126 { | 5143 { |
5127 // just to make the code more readable... | 5144 // just to make the code more readable... |
5128 i = gas_needs_gas_index; | 5145 i = index; |
5129 | 5146 |
5130 if( gas_volume_need[i] >= 65534.5 ) | 5147 if( gas_volume_need[i] >= 65534.5 ) |
5131 { | 5148 { |
5132 int_O_gas_need_vol[i] = 65535; // clip at 65535 liters | 5149 int_O_gas_need_vol[i] = 65535; // clip at 65535 liters |
5133 int_O_gas_need_pres[i] = 999 | INT_FLAG_WARNING | INT_FLAG_HIGH; // 999 bar + warning flag + >999 flag | 5150 int_O_gas_need_pres[i] = 999 | INT_FLAG_WARNING | INT_FLAG_HIGH; // 999 bar + warning flag + >999 flag |
5341 // store the current CNS value and deco warnings | 5358 // store the current CNS value and deco warnings |
5342 vault_CNS_fraction_real = CNS_fraction_real; | 5359 vault_CNS_fraction_real = CNS_fraction_real; |
5343 vault_deco_warnings = char_O_deco_warnings; | 5360 vault_deco_warnings = char_O_deco_warnings; |
5344 vault_deco_info = char_O_deco_info; | 5361 vault_deco_info = char_O_deco_info; |
5345 | 5362 |
5346 // store the tissue pressures | 5363 // copy the real pressures to the vault |
5347 for( i = 0; i < NUM_COMP; i++ ) | 5364 memcpy(vault_pres_tissue_N2, real_pres_tissue_N2, 256); |
5348 { | |
5349 vault_pres_tissue_N2[i] = real_pres_tissue_N2[i]; | |
5350 #ifdef _helium | |
5351 vault_pres_tissue_He[i] = real_pres_tissue_He[i]; | |
5352 #else | |
5353 vault_pres_tissue_He[i] = 0; | |
5354 #endif | |
5355 } | |
5356 } | 5365 } |
5357 | 5366 |
5358 static void pull_tissues_from_vault(void) | 5367 static void pull_tissues_from_vault(void) |
5359 { | 5368 { |
5360 // restore the CNS value and deco warnings | 5369 // restore the CNS value and deco warnings |
5363 char_O_deco_info = vault_deco_info; | 5372 char_O_deco_info = vault_deco_info; |
5364 | 5373 |
5365 // convert the CNS value to integer | 5374 // convert the CNS value to integer |
5366 convert_cur_CNS_for_display(); | 5375 convert_cur_CNS_for_display(); |
5367 | 5376 |
5368 // restore the tissue pressures | 5377 // copy the vault back to the real pressures |
5369 for( i = 0; i < NUM_COMP; i++ ) | 5378 memcpy(real_pres_tissue_N2, vault_pres_tissue_N2, 256); |
5370 { | |
5371 real_pres_tissue_N2[i] = vault_pres_tissue_N2[i]; | |
5372 #ifdef _helium | |
5373 real_pres_tissue_He[i] = vault_pres_tissue_He[i]; | |
5374 #else | |
5375 real_pres_tissue_He[i] = 0; | |
5376 #endif | |
5377 } | |
5378 } | 5379 } |
5379 | 5380 |
5380 | 5381 |
5381 ////////////////////////////////////////////////////////////////////////////// | 5382 ////////////////////////////////////////////////////////////////////////////// |
5382 // | 5383 // |