diff code_part1/OSTC_code_c_part2/p2_deco.c @ 200:0a3ca358c684

BUGFIX clear decotable at begin of simulator mode. + minor P2_deco cleanups and comments.
author JeanDo
date Mon, 14 Feb 2011 23:15:40 +0100
parents f15e804ff67f
children e5c484d59a91
line wrap: on
line diff
--- a/code_part1/OSTC_code_c_part2/p2_deco.c	Mon Feb 14 17:23:08 2011 +0100
+++ b/code_part1/OSTC_code_c_part2/p2_deco.c	Mon Feb 14 23:15:40 2011 +0100
@@ -75,7 +75,7 @@
 //  + Allow to abort MD2 calculation (have to restart next time).
 //
 // Literature:
-// B"uhlmann, Albert: Tauchmedizin; 4. Auflage;
+// Bühlmann, Albert: Tauchmedizin; 4. Auflage [2002];
 // Schr"oder, Kai & Reith, Steffen; 2000; S"attigungsvorg"ange beim Tauchen, das Modell ZH-L16, Funktionsweise von Tauchcomputern; http://www.achim-und-kai.de/kai/tausim/saett_faq
 // Morrison, Stuart; 2000; DIY DECOMPRESSION; http://www.lizardland.co.uk/DIYDeco.html
 // Balthasar, Steffen; Dekompressionstheorie I: Neo Haldane Modelle; http://www.txfreak.de/dekompressionstheorie_1.pdf
@@ -96,6 +96,9 @@
 #include "p2_definitions.h"
 #include "shared_definitions.h"
 
+// Water vapour partial pressure in the lumb.
+static const float ppWVapour = 0.0627;
+
 // *************************
 // ** P R O T O T Y P E S **
 // *************************
@@ -106,7 +109,6 @@
 static void calc_tissue(PARAMETER unsigned char period);
 static void calc_limit(PARAMETER float GF_current);
 
-static void calc_wo_deco_step_2s(void);
 static void clear_tissue(void);
 static void calc_ascenttime(void);
 static void update_startvalues(void);
@@ -127,7 +129,7 @@
 
 static void calc_nextdecodepth(void);
 
-//---- Bank 3 parameters -----------------------------------------------------
+//---- Bank 4 parameters -----------------------------------------------------
 #pragma udata bank4=0x400
 
 static unsigned char 	low_depth;
@@ -159,21 +161,18 @@
 static unsigned char	ci;
 static float 			pres_respiration;
 static float			pres_surface;
-static float			temp1;
 static float			temp_deco;
-static float			temp_atem;
-static float			temp2_atem;
+static float			ppO2;
+static float			ppHe;
 static float			temp_tissue;
-static float			N2_ratio;
-static float			He_ratio;
-static float 			var_N2_a;
-static float 			var_N2_b;
-static float 			var_He_a;
-static float 			var_He_b;
-static float  			var_N2_e;
-static float  			var_He_e;
-static float  			var_N2_halftime;
-static float  			var_He_halftime;
+static float			N2_ratio;       // Breathed gas nitrogen ratio.
+static float			He_ratio;       // Breathed gas helium ratio.
+static float 			var_N2_a;       // Bühlmann a, for current N2 tissue.
+static float 			var_N2_b;       // Bühlmann b, for current N2 tissue.
+static float 			var_He_a;       // Bühlmann a, for current He tissue.
+static float 			var_He_b;       // Bühlmann b, for current He tissue.
+static float  			var_N2_e;       // Exposition, for current N2 tissue.
+static float  			var_He_e;       // Exposition, for current He tissue.
 
 static float            pres_diluent;               // new in v.101
 static float            deco_diluent;               // new in v.101
@@ -181,13 +180,13 @@
 static float            deco_ppO2_change;           // new in v.101
 static float            deco_ppO2;                  // new in v.101
 
-static unsigned char    sim_gas_last_used;         // Last used gas, to detected a gas switch. 
-static unsigned char    sim_gas_delay;             // Delay added for gas switch (count down) [min].
-static float			calc_N2_ratio;			// new in v.101
-static float			calc_He_ratio;			// new in v.101
-static float			CNS_fraction;			// new in v.101
-static float			float_saturation_multiplier;		// new in v.101
-static float			float_desaturation_multiplier;		// new in v.101
+static unsigned char    sim_gas_last_used;              // Last used gas, to detected a gas switch. 
+static unsigned char    sim_gas_delay;                  // Delay added for gas switch (count down) [min].
+static float			calc_N2_ratio;                  // Simulated (switched) nitrogen ratio.
+static float			calc_He_ratio;                  // Simulated (switched) helium ratio.
+static float			CNS_fraction;			        // new in v.101
+static float			float_saturation_multiplier;    // new in v.101
+static float			float_desaturation_multiplier;  // new in v.101
 static float			float_deco_distance;	// new in v.101
 static char			    flag_in_divemode;		// new in v.108
 
@@ -407,7 +406,7 @@
 static void check_dbg(PARAMETER char is_post_check)
 {
 	overlay unsigned int temp_DBS = 0;
-    overlay char i;                     // Local loop index.
+    overlay unsigned char i;            // Local loop index.
 
 	if( (DBG_N2_ratio != N2_ratio) || (DBG_He_ratio != He_ratio) )
 		temp_DBS |= DBG_c_gas;
@@ -842,15 +841,6 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-
-void deco_calc_without_deco(void)
-{
-    RESET_C_STACK
-    calc_wo_deco_step_2s();
-    deco_calc_desaturation_time();
-}
-
-//////////////////////////////////////////////////////////////////////////////
 // Reset decompression model:
 // + Set all tissues to equilibrium with Air at ambient pressure.
 // + Reset last stop to 0m
@@ -867,7 +857,6 @@
 {
     RESET_C_STACK
     calc_wo_deco_step_1_min();
-    char_O_deco_status = 3; // surface new in v.102 overwrites value of calc_wo_deco_step_1_min
     deco_calc_desaturation_time();
 }
 
@@ -902,7 +891,7 @@
     for(ci=0; ci<16; ci++)
     {
         // cycle through the 16 Bühlmann tissues
-        overlay float p = N2_ratio * (pres_respiration -  0.0627);
+        overlay float p = N2_ratio * (pres_respiration -  ppWVapour);
         pres_tissue[ci] = p;
 
         read_buhlmann_coefficients(-1);
@@ -926,32 +915,6 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-// calc_wo_deco_step_2s
-//
-// optimized in v.101 (float_..saturation_multiplier)
-//
-// Note: fixed N2_ratio for standard air.
-
-static void calc_wo_deco_step_2s(void)
-{
-    N2_ratio = 0.7902; // Sum as stated in b"uhlmann
-    pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system
-    pres_surface = (float)int_I_pres_surface / 1000.0;  // the b"uhlmann formula using pres_surface does apply to the pressure without any inert ratio
-    temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body
-    temp2_atem = 0.0;
-    float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01;
-    float_saturation_multiplier   = char_I_saturation_multiplier   * 0.01;
-    
-    calc_tissue(0);     // update the pressure in the 32 tissues in accordance with the new ambient pressure for 2 seconds.
-    
-    clear_deco_table();
-    char_O_deco_status = 0;
-    char_O_nullzeit = 0;
-    int_O_ascenttime = 0;
-    calc_gradient_factor();
-}
-
-//////////////////////////////////////////////////////////////////////////////
 // calc_hauptroutine
 //
 // this is the major code in dive mode calculates:
@@ -993,14 +956,14 @@
     case 3: //---- At surface: start a new dive ------------------------------
     	clear_deco_table();
     	copy_deco_table();
-    	update_startvalues();
-    	low_depth = 0;
-    	char_O_deco_status = 0;     // Calc bottom-time/nullzeit next iteration.
+    	low_depth = 0;              // Reset GF history.
+    	int_O_ascenttime = 0;       // Reset DTR.
+    	char_O_nullzeit = 0;        // Reset bottom time.
+      	char_O_deco_status = 0;     // Calc bottom-time/nullzeit next iteration.
     	backup_low_depth = 255;     // backup is empty...
     	break;
 
     case 0: //---- bottom time -----------------------------------------------
-    	update_startvalues();
     	calc_nullzeit();
     	check_ndl();
    	    char_O_deco_status = 2; // calc ascent next time.
@@ -1059,11 +1022,11 @@
     
     int_temp = (int_I_pres_respiration - int_I_pres_surface) + MBAR_REACH_GASCHANGE_AUTO_CHANGE_OFF;
     
-    deco_gas_change1 = 0;
-    deco_gas_change2 = 0;
-    deco_gas_change3 = 0;
-    deco_gas_change4 = 0;
-    deco_gas_change5 = 0;
+    deco_gas_change1 = 0.0;
+    deco_gas_change2 = 0.0;
+    deco_gas_change3 = 0.0;
+    deco_gas_change4 = 0.0;
+    deco_gas_change5 = 0.0;
 
     if(char_I_deco_gas_change1)
     {
@@ -1140,16 +1103,16 @@
  	    if (pres_diluent > pres_respiration)									// new in v.101
   		    pres_diluent = pres_respiration;								    // new in v.101
     }
- 	if (pres_diluent > 0.0627)													// new in v.101
+ 	if (pres_diluent > ppWVapour)                                               // new in v.101
  	{
- 		temp_atem = N2_ratio * (pres_diluent - 0.0627);							// changed in v.101
- 		temp2_atem = He_ratio * (pres_diluent - 0.0627);						// changed in v.101
+ 		ppO2 = N2_ratio * (pres_diluent - ppWVapour);                           // changed in v.101
+ 		ppHe = He_ratio * (pres_diluent - ppWVapour);                           // changed in v.101
  		char_O_diluent = (char)(pres_diluent/pres_respiration*100.0);
  	}
  	else																		// new in v.101
  	{
- 		temp_atem = 0.0;														// new in v.101
- 		temp2_atem = 0.0;														// new in v.101
+ 		ppO2 = 0.0;                                                             // new in v.101
+ 		ppHe = 0.0;                                                             // new in v.101
  		char_O_diluent = 0;
  	}
 
@@ -1249,18 +1212,18 @@
 
     if (deco_diluent > temp_deco)
     	deco_diluent = temp_deco;
-    if (deco_diluent > 0.0627)
+    if (deco_diluent > ppWVapour)
     {
-        temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);
-        temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);
+        ppO2 = calc_N2_ratio * (deco_diluent - ppWVapour);
+        ppHe = calc_He_ratio * (deco_diluent - ppWVapour);
     }
     else
     {
-        temp_atem = 0.0;
-        temp2_atem = 0.0;
+        ppO2 = 0.0;
+        ppHe = 0.0;
     }
-    assert( 0.0 <= temp_atem  && temp_atem  < 14.0 );
-    assert( 0.0 <= temp2_atem && temp2_atem < 14.0 );
+    assert( 0.0 <= ppO2 && ppO2 < 14.0 );
+    assert( 0.0 <= ppHe && ppHe < 14.0 );
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1280,7 +1243,7 @@
             calc_nextdecodepth();
 
         //---- Finish computations once surface is reached -------------------
-        if( temp_depth_limit <= 0 )
+        if( temp_depth_limit == 0 )
       	{
     		copy_deco_table();
         	calc_ascenttime();
@@ -1316,7 +1279,7 @@
     update_startvalues();
     clear_deco_table();
 
-   	temp_deco = pres_respiration;
+   	temp_deco = pres_respiration;       // Starts from current real depth.
 
     // Loop until first top or surface is reached.
  	for(;;)
@@ -1369,12 +1332,12 @@
         read_buhlmann_coefficients(period);   // 2 sec or 1 min period.
 
         // N2
-        temp_tissue = (temp_atem - pres_tissue[ci]) * var_N2_e;
+        temp_tissue = (ppO2 - pres_tissue[ci]) * var_N2_e;
         temp_tissue_safety();
         pres_tissue[ci] += temp_tissue;
 
         // He
-        temp_tissue = (temp2_atem - (pres_tissue+16)[ci]) * var_He_e;
+        temp_tissue = (ppHe - (pres_tissue+16)[ci]) * var_He_e;
         temp_tissue_safety();
         (pres_tissue+16)[ci] += temp_tissue;
     }
@@ -1436,6 +1399,7 @@
 static void calc_nullzeit(void)
 {
     overlay int loop;
+    update_startvalues();
     
 	char_O_nullzeit = 0;
 	for(loop = 1; loop <= 17; loop++)
@@ -1547,12 +1511,12 @@
         read_buhlmann_coefficients(period);  // 1 or 10 minute(s) interval
 
         // N2
-        temp_tissue = (temp_atem - sim_pres_tissue[ci]) * var_N2_e;
+        temp_tissue = (ppO2 - sim_pres_tissue[ci]) * var_N2_e;
         temp_tissue_safety();
         sim_pres_tissue[ci] += temp_tissue;
         
         // He
-        temp_tissue = (temp2_atem - (sim_pres_tissue+16)[ci]) * var_He_e;
+        temp_tissue = (ppHe - (sim_pres_tissue+16)[ci]) * var_He_e;
         temp_tissue_safety();
         (sim_pres_tissue+16)[ci] += temp_tissue;
     }
@@ -1636,10 +1600,11 @@
 static void update_deco_table()
 {
     overlay unsigned char x;
+    assert( temp_depth_limit < 128 ); // Can't be negativ (overflown).
 
     for(x=0; x<32; ++x)
     {
-        if( internal_deco_depth[x] == temp_depth_limit)
+        if( internal_deco_depth[x] == temp_depth_limit )
         {
             // Do not overflow (max 255')
 	        if( internal_deco_time[x] < 255 )
@@ -1730,6 +1695,7 @@
 void deco_calc_desaturation_time(void)
 {
     overlay unsigned int desat_time;    // For a particular compartiment, in min.
+    overlay float temp1;
     overlay float temp2;
     overlay float temp3;
     overlay float temp4;
@@ -1737,23 +1703,23 @@
 
     N2_ratio = 0.7902; // FIXED sum as stated in b"uhlmann
     pres_surface = (float)int_I_pres_surface / 1000.0;
-    temp_atem = N2_ratio * (pres_surface - 0.0627);
+    ppO2 = N2_ratio * (pres_surface - ppWVapour);
     int_O_desaturation_time = 0;
     float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101	(70,42%/100.=142)
     
     for (ci=0;ci<16;ci++)
     {
-        var_N2_halftime = buhlmann_ht[ci];
-        var_He_halftime = (buhlmann_ht+16)[ci];
+        overlay float var_N2_halftime = buhlmann_ht[ci];
+        overlay float var_He_halftime = (buhlmann_ht+16)[ci];
 
         // saturation_time (for flight) and N2_saturation in multiples of halftime
         // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time )
         // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time )
         // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and noFly calculations
         // N2
-        temp1 = 1.05 * temp_atem;
+        temp1 = 1.05 * ppO2;
         temp1 = temp1 - pres_tissue[ci];
-        temp2 = temp_atem - pres_tissue[ci];
+        temp2 = ppO2 - pres_tissue[ci];
         if (temp2 >= 0.0)
         {
             temp1 = 0;
@@ -1843,15 +1809,15 @@
     N2_ratio = 0.7902; // FIXED, sum lt. buehlmann
     pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system
     pres_surface = (float)int_I_pres_surface / 1000.0;  // the b"uhlmann formula using pres_surface does not use the N2_ratio
-    temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body
-    temp2_atem = 0.0;
+    ppO2 = N2_ratio * (pres_respiration - ppWVapour); // ppWVapour is the extra pressure in the body
+    ppHe = 0.0;
     float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101	(70,42%/100.=142)
     float_saturation_multiplier   = char_I_saturation_multiplier   * 0.01;
     
     calc_tissue(1);  // update the pressure in the 32 tissues in accordance with the new ambient pressure
     
     clear_deco_table();
-    char_O_deco_status = 0;
+    char_O_deco_status = 3;     // surface new in v.102 : stays in surface state.
     char_O_nullzeit = 0;
     int_O_ascenttime = 0;
     calc_gradient_factor();
@@ -2029,6 +1995,7 @@
 // new in v.101
 //
 // calculates the half time of 90 minutes in 6 steps of 15 min
+// (Used in sleepmode, for low battery mode).
 //
 // Output: char_O_CNS_fraction
 // Uses and Updates: CNS_fraction
@@ -2047,6 +2014,8 @@
 //
 // calculates int_I_temp * char_I_temp / 100
 // output is int_I_temp
+//
+// Used to compute NoFly remaining time.
 
 void deco_calc_percentage(void)
 {