Mercurial > public > hwos_code
diff 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 |
line wrap: on
line diff
--- a/src/p2_deco.c Fri Mar 04 08:30:23 2022 +0100 +++ b/src/p2_deco.c Sun Aug 28 13:13:38 2022 +0200 @@ -1,5 +1,5 @@ // *************************************************************************** -// p2_deco.c combined next generation V3.12.1 +// p2_deco.c combined next generation V3.19.4 // // Created on: 12.05.2009 // Author: heinrichs weikamp, contributions by Ralph Lembcke and others @@ -89,12 +89,17 @@ #include <math.h> +#include <string.h> #include "p2_definitions.h" #define TEST_MAIN #include "shared_definitions.h" #include "configuration.inc" +// work-around for a C18 compiler bug (to avoid a warning been thrown for valid code) +#define memcpy(a,b,c) memcpy((a),(const void*)(b),(c)) + + // ********************************************************************************************************************************* // // C O N S T A N T S D E F I N I T I O N S @@ -216,12 +221,8 @@ #define PHASE_40_BOTTOM_GAS_NEED 0x40 // calculate gas needs for bottom segment #define PHASE_50_NDL_TIME 0x50 // calculate NDL time #define PHASE_70_ASCENT_OR_RETURN 0x70 // calculate open water ascent or cave return -#define PHASE_80_RESULTS 0x80 // results - initialization -#define PHASE_81_RESULTS_STOPS_TABLE 0x81 // results - publish stops table -#define PHASE_82_RESULTS_NDL 0x82 // results - publish data / within NDL -#define PHASE_83_RESULTS_DECO 0x83 // results - publish data / in deco -#define PHASE_84_GAS_NEEDS_PRESSURES 0x84 // results - convert gas needs from volumes to pressures -#define PHASE_85_GAS_NEEDS_CAVE 0x85 // results - tag gas needs as calculated in cave or open water mode +#define PHASE_80_RESULTS 0x80 // results - NDL, TTS, TST +#define PHASE_81_GAS_NEEDS_PRESSURES 0x81 // results - convert gas needs from volumes to pressures #define PHASE_90_FINISH 0x90 // finish calculation cycle @@ -280,7 +281,7 @@ // gas_take_current() or gas_find_best()/gas_take_best() and gas_set_ratios(). static void calc_tissues(void); // Updates the tissues dependent on the partial pressures of N2 and He. static void calc_CNS(void); // Updates the CNS value dependent on the partial pressure of the O2. -static void calc_limit(PARAMETER float GF_current); +static void calc_limit(PARAMETER float GF_parameter); // Calculates ceiling, current supersaturation factor and some more data. // Functions for TR @@ -305,7 +306,8 @@ static void update_deco_table(PARAMETER unsigned char time_increment); // Enters a new stop or extends an existing stop in the deco stops table. static void calc_required_volume(void); // Calculates gas volume required for a given depth, time and usage (SAC rate). -static void convert_volume_to_pressure(void); // Converts gas volumes into pressures and sets respective flags. +static void convert_volume_to_pressure(PARAMETER unsigned char index); + // Converts gas volumes into pressures and sets respective flags. // Functions for Results Reporting static void publish_deco_table(void); // Copies the internal deco stops table to the export interface. @@ -321,7 +323,7 @@ static void read_CNS_ab_coefficient(void); // Reads the CNS a and b coefficients from a ROM table. static void read_CNS_c_coefficient(void); // Reads the CNS c coefficient from a ROM table. static void read_Buhlmann_coefficients(void); // Reads the Buhlmann a and b coefficients from a ROM table. -static void read_Buhlmann_times(PARAMETER char period); +static void read_Buhlmann_times(PARAMETER unsigned char period); // Reads pre-computed tissue increment factors from a ROM table. static void read_Buhlmann_ht(void); // Reads the half-times from a ROM table. static void adopt_Buhlmann_coefficients(void); // Computes average a and b coefficient by the N2/He tissue ratio. @@ -338,14 +340,81 @@ // // ********************************************************************************************************************************* + +//---- Bank 13 parameters ----------------------------------------------------- +#ifndef UNIX +# pragma udata overlay bank13=0xd00 +static char C_STACK[256]; // C-code data stack +# define C_STACK_ADDR C_STACK +#endif + +// 256 byte used, bank is full + + +//---- Bank 7 parameters ----------------------------------------------------- +#ifndef UNIX +# pragma udata bank7=0x700 +#endif + +// tissue pressures for the real tissues (128 byte) + +static float real_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes || keep order and position of these variables as +static float real_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes || they are backed-up to & restored from EEPROM! + +// delta-pressures for the real tissue pressures (128 byte) + +static float real_pres_delta_N2[NUM_COMP]; // 16 floats = 64 bytes +static float real_pres_delta_He[NUM_COMP]; // 16 floats = 64 bytes + +// 256 byte used, bank is full + + +//---- Bank 8 parameters ----------------------------------------------------- +#ifndef UNIX +# pragma udata bank8=0x800 +#endif + +// tissue pressures for the simulated tissues (128 byte) + +static float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes +static float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes + +// delta-pressures for the simulated tissues (128 byte) + +static float sim_pres_delta_N2[NUM_COMP]; // 16 floats = 64 bytes +static float sim_pres_delta_He[NUM_COMP]; // 16 floats = 64 bytes + +// 256 byte used, bank is full + + +//---- Bank 12 parameters ----------------------------------------------------- + +#ifndef UNIX +# pragma udata bank12=0xc00 +#endif + +// vault for backing up real tissue pressures (128 byte) + +static float vault_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes +static float vault_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes + +// vault for backing up real delta-pressures (128 byte) + +static float vault_pres_delta_N2[NUM_COMP]; // 16 floats = 64 bytes +static float vault_pres_delta_He[NUM_COMP]; // 16 floats = 64 bytes + +// 256 byte used, bank is full + + //---- Bank 5 parameters ----------------------------------------------------- #ifndef UNIX # pragma udata bank5=0x500 #endif -// Data that go into the deco data vault (4 byte) - -static float CNS_fraction_real; // || current real CNS (1.00 = 100%) +// Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 5, i.e. at address 0x500 ! + +static volatile unsigned short tmr5_value; // | timer 5 value buffer MUST be at address 0x500 +static volatile unsigned char tmr5_overflow; // | timer 5 overflow flag MUST be at address 0x502 // Environmental and Gas Data (51 byte) @@ -394,8 +463,9 @@ static unsigned char peer_tank[NUM_GAS]; // bit flag vector indicating peer tanks holding same gas -// real Context: what we are doing now (12 byte) - +// real Context: what we are doing now (16 byte) + +static float CNS_fraction_real; // current real CNS (1.00 = 100%) static unsigned short IBCD_tissue_vector; // 16 bit vector to memorize all tissues that experience IBCD static float pres_respiration_sac; // used in SAC calculation: current depth in absolute pressure @@ -430,7 +500,7 @@ static unsigned short int_time; // time it takes for the compartment to reach the target pressure -// Gas in Use and Gas Needs (67 byte) +// Gas in Use and Gas Needs (66 byte) static unsigned char start_gas_num; // number of the gas/dil to start with @@ -441,7 +511,6 @@ static unsigned char sim_gas_best_num; // number of the best gas available static unsigned char sim_gas_best_depth; // change depth of the best gas available -static unsigned char gas_needs_gas_index; // index to the gas and tank data arrays static float gas_volume_need[NUM_GAS]; // gas volumes required for ascent / cave return in liters static float gas_volume_avail[NUM_GAS]; // gas volumes available for ascent / cave return in liters static float gas_volume_atten[NUM_GAS]; // attention threshold for gas volumes available @@ -455,7 +524,13 @@ static float gas_needs_volume_due; // computed amount of required gas volume -// 243 byte used, 13 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) +// Transfer Values for convert_float_to_int() (6 byte) + +static float float_value; // input value, float +static unsigned short int_value; // output value, 16 bit + + +// 251 byte used, 5 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) //---- Bank 6 parameters ----------------------------------------------------- @@ -463,13 +538,7 @@ # pragma udata bank6=0x600 #endif -// Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 6, i.e. at address 0x600 ! - -static volatile unsigned short tmr5_value; // | timer 5 value buffer MUST be at address 0x600 -static volatile unsigned char tmr5_overflow; // | timer 5 overflow flag MUST be at address 0x602 - - -// Modes, Sequencing and Indexing (14 byte) +// Modes, Sequencing and Indexing (17 byte) static unsigned char main_status; // shadow register for char_O_main_status static unsigned char deco_status; // shadow register for char_O_deco_status @@ -487,9 +556,10 @@ static unsigned char backtrack_index; // index into the depth backtracking array char_I_backtrack_storage static unsigned char backtrack_target_depth; // current backtracking target depth static unsigned char backtrack_step_counter; // counter for number of 1/10 minute steps done - - -// Result Values from Calculation Functions (28 byte) +static unsigned char spare; // UNUSED YET, placed here for alignment purpose + + +// Result Values from Calculation Functions (30 byte) static float ppO2_O2; // ppO2 calculated for breathing pure oxygen in OC mode static float ppO2_OC; // ppO2 calculated for breathing current gas in OC mode @@ -519,13 +589,6 @@ static float var_He_ht; // half-time for current He tissue -// CNS Coefficients (10 byte) - -static float var_cns_gain; // two coefficients approximation, gain -static float var_cns_offset; // two coefficients approximation, offset -static unsigned short var_cns_value; // one coefficient approximation, value - - // Auxiliary Variables for Data Buffering (28 byte) static float N2_equilibrium; // used for N2 tissue graphics scaling @@ -533,14 +596,29 @@ static float float_pSCR_factor; // pre-computed factor for pSCR ppO2 drop calculation static float calc_pres_tissue_N2; // auxiliary variable to buffer tissue N2 pressure static float calc_pres_tissue_He; // auxiliary variable to buffer tissue He pressure -static float pres_tissue; // auxiliary variable to buffer total tissue pressure +static float calc_pres_tissue; // auxiliary variable to buffer total tissue pressure static float old_pres_respiration; // auxiliary variable to buffer sim_pres_respiration -// Transfer Values for convert_float_to_int() (6 byte) - -static float float_value; // input value, float -static unsigned short int_value; // output value, 16 bit +// CNS Coefficients (10 byte) + +static float var_cns_gain; // two coefficients approximation, gain +static float var_cns_offset; // two coefficients approximation, offset +static unsigned short var_cns_value; // one coefficient approximation, value + + +// Vault to back-up & restore Tissue related Data (6 byte) + +static float vault_CNS_fraction_real; // stores CNS percentage (1.0 = 100%) +static unsigned char vault_deco_warnings; // stores warnings status +static unsigned char vault_deco_info; // stores info status + + +// stops table (96 byte) + +static unsigned char internal_deco_depth[NUM_STOPS]; // depths of the stops in meters +static unsigned char internal_deco_time[NUM_STOPS]; // durations of the stops in minutes +static unsigned char internal_deco_gas[NUM_STOPS]; // gases used on the stops (0 / 1-5) // Performance Profiling (4 byte) @@ -550,67 +628,17 @@ static unsigned char profiling_phase; // performance measurement: current calculation phase -// 7 byte occupied by compiler-placed vars - - -// 139 byte used, 117 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) - - - -//---- Bank 12 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata bank12=0xc00 -#endif - -// stops table (96 byte) - -static unsigned char internal_deco_depth[NUM_STOPS]; // depths of the stops in meters -static unsigned char internal_deco_time[NUM_STOPS]; // durations of the stops in minutes -static unsigned char internal_deco_gas[NUM_STOPS]; // gases used on the stops (0 / 1-5) - - -// Vault to back-up & restore Tissue related Data (134 byte) - -static float vault_pres_tissue_N2[NUM_COMP]; // stores the nitrogen tissue pressures -static float vault_pres_tissue_He[NUM_COMP]; // stores the helium tissue pressures -static float vault_CNS_fraction_real; // stores CNS percentage (1.0 = 100%) -static unsigned char vault_deco_warnings; // stores warnings status -static unsigned char vault_deco_info; // stores info status - -// 230 byte used, 26 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) - - -//---- Bank 7 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata bank7=0x700 -#endif - -// Keep order and position of the variables in bank 7 as they are backed-up to & restored from EEPROM - -static float real_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes -static float real_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes - -static float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes -static float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes - -// 256 byte used, bank is full - - -//---- Bank 8 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata overlay bank8=0x800 - -static char md_pi_subst[256]; // overlay C-code data stack here, too - -# define C_STACK md_pi_subst -#endif - - -// Back to bank6 for further tmp data -// Do not delete this assignment, it is needed by the compiler/linker. -#ifndef UNIX -# pragma udata bank6 -#endif +// Function Parameters placed by the C Compiler (7 byte) +/* +static unsigned char period +static float parameter +static unsigned char time_increment +static unsigned char time_interval +*/ + + +// 238 byte used, 18 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) + // ********************************************************************************************************************************* @@ -850,21 +878,21 @@ void fillDataStack(void) { _asm - LFSR 1,C_STACK + LFSR 1,C_STACK_ADDR MOVLW 0xCC loop: MOVWF POSTINC1,0 TSTFSZ FSR1L,0 BRA loop - LFSR 1,C_STACK - LFSR 2,C_STACK + LFSR 1,C_STACK_ADDR + LFSR 2,C_STACK_ADDR _endasm } # else -# define RESET_C_STACK \ - _asm \ - LFSR 1,C_STACK \ - LFSR 2,C_STACK \ +# define RESET_C_STACK \ + _asm \ + LFSR 1,C_STACK_ADDR \ + LFSR 2,C_STACK_ADDR \ _endasm # endif #endif @@ -882,8 +910,8 @@ { #ifndef CROSS_COMPILE _asm - movff 0x601,0xF7D // bank-safe load TMR5H from C variable tmr5_value first - movff 0x600,0xF7C // bank-safe load TMR5L from C variable tmr5_value thereafter + movff 0x501,0xF7D // bank-safe load TMR5H from C variable tmr5_value first + movff 0x500,0xF7C // bank-safe load TMR5L from C variable tmr5_value thereafter bcf 0xFBA,1,0 // clear timer 5 overrun flag (0xFBA = PIR5, bit 1 = TMR5IF) _endasm #else @@ -905,12 +933,12 @@ { #ifndef CROSS_COMPILE _asm - movff 0xF7C,0x600 // copy TMR5L to C variable tmr5_value, low byte first - movff 0xF7D,0x601 // copy TMR5H to C variable tmr5_value, high byte thereafter + movff 0xF7C,0x500 // copy TMR5L to C variable tmr5_value, low byte first + movff 0xF7D,0x501 // copy TMR5H to C variable tmr5_value, high byte thereafter clrf WREG,0 // clear WREG to 0x00 = no overrun by default btfsc 0xFBA,1,0 // did timer 5 overrun? (0xFBA = PIR5, bit 1 = TMR5IF) setf WREG,0 // YES - set WREG to 0xff = overrun detected - movff WREG,0x602 // copy WREG to C variable tmr5_overflow + movff WREG,0x502 // copy WREG to C variable tmr5_overflow _endasm #else return; @@ -998,7 +1026,7 @@ // If period == 0 : 2 sec interval // 1 : 1 min interval // 2 : 10 min interval -static void read_Buhlmann_times(PARAMETER char period) +static void read_Buhlmann_times(PARAMETER unsigned char period) { #ifndef CROSS_COMPILE // Note: We don't use far ROM pointer, because handling @@ -1094,7 +1122,7 @@ // var_He_a, var_He_b coefficients for He // calc_pres_tissue_N2 partial pressure of N2 in tissue // calc_pres_tissue_He partial pressure of He in tissue -// pres_tissue total pressure in tissue +// calc_pres_tissue total pressure in tissue // // Output: var_a, var_b coefficients adopted by N2/He ratio // @@ -1104,8 +1132,8 @@ #ifdef _helium - var_a = (var_N2_a * calc_pres_tissue_N2 + var_He_a * calc_pres_tissue_He) / pres_tissue; - var_b = (var_N2_b * calc_pres_tissue_N2 + var_He_b * calc_pres_tissue_He) / pres_tissue; + var_a = (var_N2_a * calc_pres_tissue_N2 + var_He_a * calc_pres_tissue_He) / calc_pres_tissue; + var_b = (var_N2_b * calc_pres_tissue_N2 + var_He_b * calc_pres_tissue_He) / calc_pres_tissue; #else @@ -2058,6 +2086,9 @@ real_pres_tissue_He[ci] = 0.0; // He real_pres_tissue_N2[ci] = N2_equilibrium; // N2 + real_pres_delta_He[ci] = 0.0; // He + real_pres_delta_N2[ci] = 0.0; // N2 + // reset tissue pressures for scaled tissue graphics char_O_tissue_pres_He[ci] = 0; // He char_O_tissue_pres_N2[ci] = 10; // N2 @@ -2161,7 +2192,7 @@ main_status = char_O_main_status; deco_status = char_O_deco_status; - // clear all command flags on the master mode to signal that the command is read + // clear all command flags on the master mode to signal that the command is read and in processing char_O_deco_status &= ~COMMAND_MASK; // clear the initialization flag on the shadow copy @@ -2183,7 +2214,7 @@ main_status = char_O_main_status; deco_status = char_O_deco_status; - // clear all command flags on the master mode to signal that the command is read + // clear all command flags on the master mode to signal that the command is read and in processing char_O_deco_status &= ~COMMAND_MASK; // set the calculation phase to start with to doing the cyclic initialization @@ -2325,7 +2356,7 @@ // (7 meters chosen as to be 2 stop depth intervals plus 1 additional meter below) if ( ( deco_info & DECO_MODE ) > 0 ) if ( ( char_depth_real ) > char_O_deco_depth[0] + 7 ) - deco_info &= ~DECO_MODE; + deco_info &= ~DECO_MODE; // Set the deco mode flag if: // deco mode is not set @@ -2340,7 +2371,7 @@ || ( char_I_current_gas_type == 0 ) || ( char_O_deco_depth[0] > 0 ) ) - deco_info |= DECO_MODE; + deco_info |= DECO_MODE; //---- Compute ppO2 Warnings ------------------------------------------------------------------ @@ -2511,11 +2542,7 @@ else deco_info &= ~DECO_STOPS_ALT; // initialize the simulated tissues with the current state of the real tissues - for( i = 0; i < NUM_COMP; i++ ) - { - sim_pres_tissue_N2[i] = real_pres_tissue_N2[i]; - sim_pres_tissue_He[i] = real_pres_tissue_He[i]; - } + memcpy(sim_pres_tissue_N2, real_pres_tissue_N2, 256); // initialize the gas types for( i = 0; i < NUM_GAS; i++ ) @@ -2632,9 +2659,6 @@ NDL_tissue = NDL_tissue_start; NDL_tissue_lead = NDL_tissue_start; - // initialization for convert_volume_to_pressure() - gas_needs_gas_index = 0; - // tag gas needs as not calculated in fTTS mode by default deco_info &= ~GAS_NEEDS_fTTS; @@ -2934,8 +2958,8 @@ // shall calculate gas needs? if( main_status & CALC_VOLUME ) { - overlay unsigned char index_last_gas = sim_gas_last_num-1; - overlay unsigned char index_curr_gas = sim_gas_current_num-1; + overlay unsigned char index_last_gas = sim_gas_last_num - 1; + overlay unsigned char index_curr_gas = sim_gas_current_num - 1; #ifdef _cave_mode // in cave mode? @@ -3087,7 +3111,7 @@ TTS_time += 1; } - } // overlay + } // calculate absolute pressure at the current depth sim_pres_respiration = (float)char_depth_sim * METER_TO_BAR + pres_surface; @@ -3117,132 +3141,94 @@ // convert the CNS value to integer convert_sim_CNS_for_display(); - // normal or alternative plan? - if( deco_status & CALC_NORM ) - { - // normal plan - export the integer CNS value - int_O_CNS_norm = int_sim_CNS_fraction; - } - else - { - // alternative plan - export the integer CNS value - int_O_CNS_alt = int_sim_CNS_fraction; - } - // limit total time to surface to display max. and rescale to full minutes if( TTS_time < 9995 ) TTS_time = (TTS_time + 5) / 10; else TTS_time = 999 | INT_FLAG_INVALID; - // The next calculation phase will - // - publish the stops table if in normal plan mode, - // - proceed with remaining results dependent on if within NDL, or - // - in deco - if ( deco_status & CALC_NORM ) next_planning_phase = PHASE_81_RESULTS_STOPS_TABLE; - else if ( NDL_time ) next_planning_phase = PHASE_82_RESULTS_NDL; - else next_planning_phase = PHASE_83_RESULTS_DECO; - - break; - - - /// - //--- Publish Stops Table ----------------------------------------------------------------- - // - case PHASE_81_RESULTS_STOPS_TABLE: - - // publish the stops table to the display functions - publish_deco_table(); - - // When entering deco and the ceiling depth becomes > 0 but the - // deco calculation reveals no distinct deco stop yet because - // the deco obligation will vanish during the ascent, create an - // artificial stop to signal that expedite surfacing ("popping - // up") is not allowed anymore. - if( char_O_deco_depth[0] == 0 ) // simulated ascent reveals no required stops - if( int_O_ceiling > 0 ) // real tissues have a ceiling - { - // set a pro forma stop at the configured last stop depth - char_O_deco_depth[0] = char_I_last_stop_depth; - - // set a stop time of 0 minutes, this will be displayed as "..'" - char_O_deco_time[0] = 0; - } - - // The next calculation phase will publish the main results dependent on being - // - within NDL, - // - in deco. - if ( NDL_time ) next_planning_phase = PHASE_82_RESULTS_NDL; - else next_planning_phase = PHASE_83_RESULTS_DECO; - - break; - - - /// - //--- Results - within NDL ---------------------------------------------------------------- - // - case PHASE_82_RESULTS_NDL: + // limit total stops time to display max. + if( TST_time > 999 ) TST_time = 999 | INT_FLAG_INVALID; // normal or alternative plan? if( deco_status & CALC_NORM ) { - // normal plan - output the NDL and TTS time - int_O_NDL_norm = NDL_time; - int_O_TTS_norm = TTS_time; - - // clear the stops time - int_O_TST_norm = 0; + // normal plan + + // export the integer CNS value + int_O_CNS_norm = int_sim_CNS_fraction; + + // publish the stops table to the display functions + publish_deco_table(); + + // When in deco and the ceiling depth is > 0 but the deco calculation + // reveals no distinct deco stop yet because the deco obligation will + // vanish during the ascent, create an artificial stop to signal that + // expedite surfacing ("popping up") is not allowed any more. + if( char_O_deco_depth[0] == 0 ) // simulated ascent reveals no required stops + if( int_O_ceiling > 0 ) // real tissues have a ceiling + { + // set a pro forma stop at the configured last stop depth + char_O_deco_depth[0] = char_I_last_stop_depth; + + // set a stop time of 0 minutes, this will be displayed as "..'" + char_O_deco_time[0] = 0; + } + + // within NDL? + if ( NDL_time ) + { + // YES - output the NDL and TTS time + int_O_NDL_norm = NDL_time; + int_O_TTS_norm = TTS_time; + + // clear the stops time + int_O_TST_norm = 0; + } + else + { + // NO - clear the normal NDL time + int_O_NDL_norm = 0; + + // export the TTS and total stops time + int_O_TTS_norm = TTS_time; + int_O_TST_norm = TST_time; + } } else { - // alternative plan - output the NDL time - int_O_NDL_alt = NDL_time; - int_O_TTS_alt = TTS_time; - - // clear the alternative TTS and stops time - int_O_TST_alt = 0 + INT_FLAG_ZERO; + // alternative plan + + // export the integer CNS value + int_O_CNS_alt = int_sim_CNS_fraction; + + // within NDL? + if ( NDL_time ) + { + // YES - output the NDL time + int_O_NDL_alt = NDL_time; + int_O_TTS_alt = TTS_time; + + // clear the alternative TTS and stops time + int_O_TST_alt = 0 + INT_FLAG_ZERO; + } + else + { + // NO - clear the alternative NDL time + int_O_NDL_alt = 0; + + // export the TTS and total stops time + int_O_TTS_alt = TTS_time; + int_O_TST_alt = TST_time; + } } + // export deco infos and warnings + char_O_deco_info = deco_info; + char_O_deco_warnings = deco_warnings; + // The next calculation phase will // - convert the gas needs from volume to pressure if gas needs calculation is configured // - else finish the calculation cycle - if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES; - else next_planning_phase = PHASE_90_FINISH; - - break; - - - /// - //--- Results - in Deco ------------------------------------------------------------------- - // - case PHASE_83_RESULTS_DECO: - - // limit total stops time to display max. - if( TST_time > 999 ) TST_time = 999 | INT_FLAG_INVALID; - - - // normal or alternative plan? - if( deco_status & CALC_NORM ) - { - // normal plan - clear the normal NDL time - int_O_NDL_norm = 0; - - // export the TTS and total stops time - int_O_TTS_norm = TTS_time; - int_O_TST_norm = TST_time; - } - else - { - // alternative plan - clear the alternative NDL time - int_O_NDL_alt = 0; - - // export the TTS and total stops time - int_O_TTS_alt = TTS_time; - int_O_TST_alt = TST_time; - } - - // The next calculation phase will - // - convert the gas needs from volume to pressure if gas needs calculation is configured - // - else finish the calculation cycle - if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES; + if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_81_GAS_NEEDS_PRESSURES; else next_planning_phase = PHASE_90_FINISH; break; @@ -3251,49 +3237,28 @@ // //--- Results - convert Gas Needs Volumes to Pressures ------------------------------------ // - case PHASE_84_GAS_NEEDS_PRESSURES: - - // convert required volume of the gas pointed to by gas_needs_gas_index - // into the respective pressure and set the flags - convert_volume_to_pressure(); - - // increment index to address next gas - gas_needs_gas_index++; - - // if all gases have been converted, advance to next calculation phase -#ifdef _cave_mode - if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_85_GAS_NEEDS_CAVE; -#else - if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_90_FINISH; -#endif - - break; - + case PHASE_81_GAS_NEEDS_PRESSURES: + + // step through all gases + for (i = 0; i < NUM_GAS; i++) + { + // convert required volume of the gas into the respective pressure and set the flags + convert_volume_to_pressure(i); + } #ifdef _cave_mode - // - //--- Results - tag Gas Needs as Cave or Open Water Mode ---------------------------------- - // - case PHASE_85_GAS_NEEDS_CAVE: - - // in cave mode? - if( main_status & CAVE_MODE ) - { - // YES - tag gas needs as calculated in cave mode (return along recorded depth profile) - deco_info |= GAS_NEEDS_CAVE; - } - else - { - // NO - tag gas needs as calculated in open water mode (vertical ascent) - deco_info &= ~GAS_NEEDS_CAVE; - } + // tag gas needs as calculated in cave mode or in open water mode + if( main_status & CAVE_MODE ) deco_info |= GAS_NEEDS_CAVE; + else deco_info &= ~GAS_NEEDS_CAVE; + + // export updated deco info + char_O_deco_info = deco_info; +#endif // advance to next calculation phase next_planning_phase = PHASE_90_FINISH; break; -#endif - // //--- finish Calculation Cycle ------------------------------------------------------------ @@ -3309,16 +3274,15 @@ if( !(int_O_TTS_alt & INT_FLAG_INVALID) ) if( !(deco_status & BAILOUT_MODE ) ) { - if( int_O_TTS_alt < int_O_TTS_norm ) deco_info |= DECO_ZONE; - if( int_O_TTS_alt > int_O_TTS_norm ) deco_info &= ~DECO_ZONE; + if ( int_O_TTS_alt < int_O_TTS_norm ) deco_info |= DECO_ZONE; + else if( int_O_TTS_alt > int_O_TTS_norm ) deco_info &= ~DECO_ZONE; + + // export updated deco info + char_O_deco_info = deco_info; } - // export updated deco infos and warnings - char_O_deco_info = deco_info; - char_O_deco_warnings = deco_warnings; - - // restore command flag to indicate that deco calculation cycle has finished - char_O_deco_status = deco_status; + // restore command flag to indicate that the deco calculation cycle has finished + char_O_deco_status = deco_status; // signal end of deco calculation next_planning_phase = PHASE_00_DONE; @@ -3471,13 +3435,13 @@ static void calc_tissues() { overlay unsigned char period; - overlay float temp_tissue_N2; + overlay float last_press_tissue; + overlay float delta_press_N2; #ifdef _helium - overlay float temp_tissue_He; + overlay float delta_press_He; #endif - assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m @@ -3506,43 +3470,100 @@ do { - //---- N2 -------------------------------------------------------- - - temp_tissue = (tissue_increment & TISSUE_SELECTOR) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; - - temp_tissue = (ppN2 - temp_tissue) * var_N2_e; - - apply_saturation_factors(); - - if( tissue_increment & TISSUE_SELECTOR ) + if (tissue_increment & TISSUE_SELECTOR) { - temp_tissue_N2 = temp_tissue; - real_pres_tissue_N2[ci] += temp_tissue; + //---- real N2 -------------------------------------- + + // get the real tissue pressure + last_press_tissue = real_pres_tissue_N2[ci]; + + // calculate the pressure change + temp_tissue = (ppN2 - last_press_tissue) * var_N2_e; + + // apply the saturation / desaturation factor on temp_tissue + apply_saturation_factors(); + + // store the pressure change for IBCD check and tissue graphics + delta_press_N2 = temp_tissue; + + // update the delta accumulator + real_pres_delta_N2[ci] += temp_tissue; + + // update the real tissue pressure + real_pres_tissue_N2[ci] += real_pres_delta_N2[ci]; + + // reduce the delta accumulator + real_pres_delta_N2[ci] -= real_pres_tissue_N2[ci] - last_press_tissue; + +#ifdef _helium + //---- real He -------------------------------------- + + // get the real tissue pressure + last_press_tissue = real_pres_tissue_He[ci]; + + // calculate the pressure change + temp_tissue = (ppHe - last_press_tissue) * var_He_e; + + // apply the saturation / desaturation factor on temp_tissue + apply_saturation_factors(); + + // store the pressure change for IBCD check and tissue graphics + delta_press_He = temp_tissue; + + // update the delta accumulator + real_pres_delta_He[ci] += temp_tissue; + + // update the real tissue pressure + real_pres_tissue_He[ci] += real_pres_delta_He[ci]; + + // reduce the delta accumulator + real_pres_delta_He[ci] -= real_pres_tissue_He[ci] - last_press_tissue; +#endif } else { - sim_pres_tissue_N2[ci] += temp_tissue; - } + //---- simulated N2 --------------------------------- + + // get the simulated tissue pressure + last_press_tissue = sim_pres_tissue_N2[ci]; + + // calculate the pressure change + temp_tissue = (ppN2 - last_press_tissue) * var_N2_e; + + // apply the saturation / desaturation factor on temp_tissue + apply_saturation_factors(); + + // update the delta accumulator + sim_pres_delta_N2[ci] += temp_tissue; + + // update the simulated tissue pressure + sim_pres_tissue_N2[ci] += sim_pres_delta_N2[ci]; + + // reduce the delta accumulator + sim_pres_delta_N2[ci] -= sim_pres_tissue_N2[ci] - last_press_tissue; #ifdef _helium - //---- He -------------------------------------------------------- - - temp_tissue = (tissue_increment & TISSUE_SELECTOR) ? real_pres_tissue_He[ci] : sim_pres_tissue_He[ci]; - - temp_tissue = (ppHe - temp_tissue) * var_He_e; - - apply_saturation_factors(); - - if( tissue_increment & TISSUE_SELECTOR ) - { - temp_tissue_He = temp_tissue; - real_pres_tissue_He[ci] += temp_tissue; + //---- simulated He --------------------------------- + + // get the simulated tissue pressure + last_press_tissue = sim_pres_tissue_He[ci]; + + // calculate the pressure change + temp_tissue = (ppHe - last_press_tissue) * var_He_e; + + // apply the saturation / desaturation factor on temp_tissue + apply_saturation_factors(); + + // update the delta accumulator + sim_pres_delta_He[ci] += temp_tissue; + + // update the simulated tissue pressure + sim_pres_tissue_He[ci] += sim_pres_delta_He[ci]; + + // reduce the delta accumulator + sim_pres_delta_He[ci] -= sim_pres_tissue_He[ci] - last_press_tissue; +#endif } - else - { - sim_pres_tissue_He[ci] += temp_tissue; - } -#endif //---- decrement loop counter and adjust step size --------------- @@ -3564,10 +3585,8 @@ { #ifdef _helium - // net tissue balance - temp_tissue = temp_tissue_N2 + temp_tissue_He; - + temp_tissue = delta_press_N2 + delta_press_He; // check tissue on-/off-gassing and IBCD with applying a threshold of +/-HYST // @@ -3579,14 +3598,13 @@ else if ( temp_tissue > +HYST ) // check if the tissue in on-gassing { // check for counter diffusion - if( ((temp_tissue_N2 > 0.0) && (temp_tissue_He < 0.0)) - || ((temp_tissue_N2 < 0.0) && (temp_tissue_He > 0.0)) ) + if( ((delta_press_N2 > 0.0) && (delta_press_He < 0.0)) + || ((delta_press_N2 < 0.0) && (delta_press_He > 0.0)) ) { // tag tissue as experiencing mentionable IBCD IBCD_tissue_vector |= (1 << ci); } } - #endif // For N2 tissue pressure display purpose: @@ -3594,19 +3612,19 @@ // basically keep the on-gassing / off-gassing flag from last invocation, but flip // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) char_O_tissue_pres_N2[ci] &= 128; - if ( temp_tissue_N2 > +HYST ) char_O_tissue_pres_N2[ci] = 128; // set flag for tissue pressure is increasing - else if ( temp_tissue_N2 < -HYST ) char_O_tissue_pres_N2[ci] = 0; // clear flag (-> tissue pressure is decreasing) + if ( delta_press_N2 > +HYST ) char_O_tissue_pres_N2[ci] = 128; // set flag for tissue pressure is increasing + else if ( delta_press_N2 < -HYST ) char_O_tissue_pres_N2[ci] = 0; // clear flag (-> tissue pressure is decreasing) // scale N2 tissue pressure such that the surface steady-state tissue loading // of [0.7902 * (1013 hPa - ppWater)] bar will give a 8, which aligns with // the 2nd scale line. - temp_tissue_N2 = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_N2[ci]; + delta_press_N2 = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_N2[ci]; // limit to 127 to protect the uppermost bit which holds the sat/desat flag - if (temp_tissue_N2 > 127) temp_tissue_N2 = 127; + if (delta_press_N2 > 127) delta_press_N2 = 127; // convert to integer and combine with sat/desat flag - char_O_tissue_pres_N2[ci] += (unsigned char)temp_tissue_N2; + char_O_tissue_pres_N2[ci] += (unsigned char)delta_press_N2; #ifdef _helium @@ -3615,19 +3633,18 @@ // basically keep the on-gassing / off-gassing flag from last invocation, but flip // it in case the rate exceeds a set hysteresis (actual value: see #define of HYST) char_O_tissue_pres_He[ci] &= 128; - if ( temp_tissue_He > +HYST ) char_O_tissue_pres_He[ci] = 128; // set flag for tissue pressure is increasing - else if ( temp_tissue_He < -HYST ) char_O_tissue_pres_He[ci] = 0; // clear flag (-> tissue pressure is decreasing) + if ( delta_press_He > +HYST ) char_O_tissue_pres_He[ci] = 128; // set flag for tissue pressure is increasing + else if ( delta_press_He < -HYST ) char_O_tissue_pres_He[ci] = 0; // clear flag (-> tissue pressure is decreasing) // scale He tissue pressure alike it is done for N2. // With no He in a tissue, the result will be 0. - temp_tissue_He = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_He[ci]; + delta_press_He = (8 / (0.7902 * (1.013 - ppWater))) * real_pres_tissue_He[ci]; // limit to 127 to protect the uppermost bit which holds the sat/desat flag - if (temp_tissue_He > 127) temp_tissue_He = 127; + if (delta_press_He > 127) delta_press_He = 127; // convert to integer and combine with sat/desat flag - char_O_tissue_pres_He[ci] += (unsigned char)temp_tissue_He; - + char_O_tissue_pres_He[ci] += (unsigned char)delta_press_He; // For combined tissue pressure display purpose: @@ -3638,7 +3655,7 @@ else if ( temp_tissue < -HYST ) char_O_tissue_pressure[ci] = 0; // clear flag (-> tissue pressure is decreasing) // add the two scaled pressures. - temp_tissue = temp_tissue_N2 + temp_tissue_He; + temp_tissue = delta_press_N2 + delta_press_He; // limit to 127 to protect the uppermost bit which holds the sat/desat flag if (temp_tissue > 127) temp_tissue = 127; @@ -3732,12 +3749,12 @@ } // overall tissue pressure - pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; + calc_pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; #else // get the tissue pressure - pres_tissue = ( tissue_increment & TISSUE_SELECTOR ) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; + calc_pres_tissue = ( tissue_increment & TISSUE_SELECTOR ) ? real_pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; #endif @@ -3753,14 +3770,14 @@ // check if tissue is in supersaturation - if( pres_tissue > real_pres_respiration ) + if( calc_pres_tissue > real_pres_respiration ) { // calculate maximum allowed tissue pressure at current ambient pressure pres_tissue_max = real_pres_respiration / var_b + var_a; // calculate current supersaturation value (1.0 = 100%) of this tissue according to straight Buhlmann - supersat = ( pres_tissue - real_pres_respiration ) - / ( pres_tissue_max - real_pres_respiration ); + supersat = ( calc_pres_tissue - real_pres_respiration ) + / ( pres_tissue_max - real_pres_respiration ); // calculate supersaturation value for display purpose: 1.35 = 135% = 86 pixel if( supersat <= 1.35 ) char_O_tissue_saturation[ci] = (unsigned char)(supersat * 64); @@ -3814,13 +3831,13 @@ if( char_I_model == 0 ) { // straight Buhlmann - pres_ambient_min_tissue = (pres_tissue - var_a) * var_b; + pres_ambient_min_tissue = (calc_pres_tissue - var_a) * var_b; } else { // Buhlmann with Eric Baker's varying gradient factor correction // note: this equation [1] is the inverse of equation [2] - pres_ambient_min_tissue = ( pres_tissue - (var_a * GF_parameter) ) + pres_ambient_min_tissue = ( calc_pres_tissue - (var_a * GF_parameter) ) / ( 1.0 - GF_parameter + (GF_parameter / var_b ) ); } @@ -3903,7 +3920,7 @@ #else // get the current simulated tissue pressure - pres_tissue = last_pres_tissue = sim_pres_tissue_N2[ci]; + calc_pres_tissue = last_pres_tissue = sim_pres_tissue_N2[ci]; // set the a and b coefficients adopt_Buhlmann_coefficients(); @@ -3917,7 +3934,7 @@ #ifdef _helium // calculate the total tissue pressure - pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; + calc_pres_tissue = calc_pres_tissue_N2 + calc_pres_tissue_He; // adopt a and b coefficients to current N2/He ratio inside the tissue adopt_Buhlmann_coefficients(); @@ -3938,7 +3955,7 @@ } // is the tissue pressure higher than the maximum tissue pressure allowed? - if( pres_tissue > pres_limit) + if( calc_pres_tissue > pres_limit) { // YES - tissue is outside NDL @@ -3977,7 +3994,7 @@ #else // go back to last pressure - pres_tissue = last_pres_tissue; + calc_pres_tissue = last_pres_tissue; #endif @@ -4029,7 +4046,7 @@ #else // back-up current tissue pressure - last_pres_tissue = pres_tissue; + last_pres_tissue = calc_pres_tissue; #endif @@ -4051,9 +4068,9 @@ #else // step forward tissue pressure - temp_tissue = (ppN2 - pres_tissue ) * var_N2_e; // pressure delta breathed - tissue + temp_tissue = (ppN2 - calc_pres_tissue ) * var_N2_e; // pressure delta breathed - tissue apply_saturation_factors(); // apply safety factor - pres_tissue += temp_tissue; // add pressure delta to tissue + calc_pres_tissue += temp_tissue; // add pressure delta to tissue #endif @@ -5112,7 +5129,7 @@ // // Converts gas volumes into pressures and sets respective flags // -// Input: gas_needs_gas_index index of the gas to convert (0-4) +// Input: index index of the gas to convert (0-4) // gas_volume_need[] needed gas volume in liters // char_I_gas_avail_pres[] available gas volume in bar // char_I_gas_avail_size[] size of the tanks in liters @@ -5122,10 +5139,10 @@ // int_O_gas_need_pres[] required gas amount in bar, including flags // int_O_pressure_need[] required gas amount for reading 1/2 (TR only) // -static void convert_volume_to_pressure(void) +static void convert_volume_to_pressure(PARAMETER unsigned char index) { // just to make the code more readable... - i = gas_needs_gas_index; + i = index; if( gas_volume_need[i] >= 65534.5 ) { @@ -5343,16 +5360,8 @@ vault_deco_warnings = char_O_deco_warnings; vault_deco_info = char_O_deco_info; - // store the tissue pressures - for( i = 0; i < NUM_COMP; i++ ) - { - vault_pres_tissue_N2[i] = real_pres_tissue_N2[i]; -#ifdef _helium - vault_pres_tissue_He[i] = real_pres_tissue_He[i]; -#else - vault_pres_tissue_He[i] = 0; -#endif - } + // copy the real pressures to the vault + memcpy(vault_pres_tissue_N2, real_pres_tissue_N2, 256); } static void pull_tissues_from_vault(void) @@ -5365,16 +5374,8 @@ // convert the CNS value to integer convert_cur_CNS_for_display(); - // restore the tissue pressures - for( i = 0; i < NUM_COMP; i++ ) - { - real_pres_tissue_N2[i] = vault_pres_tissue_N2[i]; -#ifdef _helium - real_pres_tissue_He[i] = vault_pres_tissue_He[i]; -#else - real_pres_tissue_He[i] = 0; -#endif - } + // copy the vault back to the real pressures + memcpy(real_pres_tissue_N2, vault_pres_tissue_N2, 256); }