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 //