Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 344:797e2ac42d24 ScreenDump
MERGE with 1.91 main trunk.
author | JeanDo |
---|---|
date | Sat, 21 May 2011 14:48:07 +0200 |
parents | ecbbbd423e86 |
children | b5b030c1ae7e |
comparison
equal
deleted
inserted
replaced
337:6bdf80d7276c | 344:797e2ac42d24 |
---|---|
75 // 2011/04/10: [jDG] Use timer TMR3 to limit loops in calc_hauptroutine_calc_deco(). | 75 // 2011/04/10: [jDG] Use timer TMR3 to limit loops in calc_hauptroutine_calc_deco(). |
76 // 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability. | 76 // 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability. |
77 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for decoplanning. | 77 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for decoplanning. |
78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor. | 78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor. |
79 // 2011/05/02: [jDG] Added "Future TTS" function (CF58). | 79 // 2011/05/02: [jDG] Added "Future TTS" function (CF58). |
80 // 2011/05/17: [jDG] Various cleanups. | |
80 // | 81 // |
81 // TODO: | 82 // TODO: |
82 // + Allow to abort MD2 calculation (have to restart next time). | 83 // + Allow to abort MD2 calculation (have to restart next time). |
83 // | 84 // |
84 // Literature: | 85 // Literature: |
161 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. | 162 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. |
162 | 163 |
163 // Real context: what we are doing now. | 164 // Real context: what we are doing now. |
164 static float calc_lead_tissue_limit; // | 165 static float calc_lead_tissue_limit; // |
165 | 166 |
166 static unsigned char internal_deco_time[32]; | 167 static unsigned char internal_deco_time[NUM_STOPS]; |
167 static unsigned char internal_deco_depth[32]; | 168 static unsigned char internal_deco_depth[NUM_STOPS]; |
168 | 169 |
169 static float cns_vault; | 170 static float cns_vault; |
170 static float pres_tissue_vault[32]; | 171 static float pres_tissue_N2_vault[NUM_COMP]; |
172 static float pres_tissue_He_vault[NUM_COMP]; | |
171 | 173 |
172 //---- Bank 5 parameters ----------------------------------------------------- | 174 //---- Bank 5 parameters ----------------------------------------------------- |
173 #pragma udata bank5=0x500 | 175 #pragma udata bank5=0x500 |
174 | 176 |
175 static unsigned char ci; | 177 static unsigned char ci; |
186 static float var_He_a; // Bühlmann a, for current He tissue. | 188 static float var_He_a; // Bühlmann a, for current He tissue. |
187 static float var_He_b; // Bühlmann b, for current He tissue. | 189 static float var_He_b; // Bühlmann b, for current He tissue. |
188 static float var_N2_e; // Exposition, for current N2 tissue. | 190 static float var_N2_e; // Exposition, for current N2 tissue. |
189 static float var_He_e; // Exposition, for current He tissue. | 191 static float var_He_e; // Exposition, for current He tissue. |
190 | 192 |
191 static float pres_diluent; // new in v.101 | 193 static float pres_diluent; // new in v.101 |
192 static float const_ppO2; // new in v.101 | 194 static float const_ppO2; // new in v.101 |
193 | 195 |
194 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch. | 196 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch. |
195 static unsigned char sim_gas_last_used; // Number of last used gas, to detected a gas switch. | 197 static unsigned char sim_gas_last_used; // Number of last used gas, to detected a gas switch. |
196 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive]. | 198 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive]. |
197 static unsigned short sim_dive_mins; // Simulated dive time. | 199 static unsigned short sim_dive_mins; // Simulated dive time. |
198 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. | 200 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. |
199 static float calc_He_ratio; // Simulated (switched) helium ratio. | 201 static float calc_He_ratio; // Simulated (switched) helium ratio. |
200 static float CNS_fraction; // new in v.101 | 202 static float CNS_fraction; // new in v.101 |
201 static float float_saturation_multiplier; // new in v.101 | 203 static float float_saturation_multiplier; // new in v.101 |
202 static float float_desaturation_multiplier; // new in v.101 | 204 static float float_desaturation_multiplier; // new in v.101 |
203 static float float_deco_distance; // new in v.101 | 205 static float float_deco_distance; // new in v.101 |
204 static char flag_in_divemode; // new in v.108 | 206 static char flag_in_divemode; // new in v.108 |
205 | 207 |
206 static unsigned char deco_gas_change[5]; // new in v.109 | 208 static unsigned char deco_gas_change[NUM_GAS]; // new in v.109 |
207 | 209 |
208 //---- Bank 6 parameters ----------------------------------------------------- | 210 //---- Bank 6 parameters ----------------------------------------------------- |
209 #pragma udata bank6=0x600 | 211 #pragma udata bank6=0x600 |
210 | 212 |
211 float pres_tissue[32]; | 213 float pres_tissue_N2[NUM_COMP]; |
214 float pres_tissue_He[NUM_COMP]; | |
212 | 215 |
213 //---- Bank 7 parameters ----------------------------------------------------- | 216 //---- Bank 7 parameters ----------------------------------------------------- |
214 #pragma udata bank7=0x700 | 217 #pragma udata bank7=0x700 |
215 | 218 |
216 float sim_pres_tissue[32]; // 32 floats = 128 bytes. | 219 float sim_pres_tissue_N2[NUM_COMP]; // 32 floats = 128 bytes. |
217 static float sim_pres_tissue_backup[32]; | 220 float sim_pres_tissue_He[NUM_COMP]; // 32 floats = 128 bytes. |
221 static float sim_pres_tissue_backup_N2[NUM_COMP]; | |
222 static float sim_pres_tissue_backup_He[NUM_COMP]; | |
218 | 223 |
219 //---- Bank 8 parameters ----------------------------------------------------- | 224 //---- Bank 8 parameters ----------------------------------------------------- |
220 #pragma udata bank8=0x800 | 225 #pragma udata bank8=0x800 |
221 | 226 |
222 static char md_pi_subst[256]; | 227 static char md_pi_subst[256]; |
326 //---- Setup some error (?) conditions ----------------------------------- | 331 //---- Setup some error (?) conditions ----------------------------------- |
327 if(char_I_deco_model) | 332 if(char_I_deco_model) |
328 int_O_DBS_bitfield |= DBS_mode; | 333 int_O_DBS_bitfield |= DBS_mode; |
329 if(const_ppO2) | 334 if(const_ppO2) |
330 int_O_DBS_bitfield |= DBS_ppO2; | 335 int_O_DBS_bitfield |= DBS_ppO2; |
331 for(i = 16; i < 32; i++) | 336 for(i = 0; i < NUM_COMP; i++) |
332 if(pres_tissue[i]) | 337 if(pres_tissue_He[i]) |
333 int_O_DBS_bitfield |= DBS_HE_sat; | 338 int_O_DBS_bitfield |= DBS_HE_sat; |
334 if(float_saturation_multiplier < 0.99) | 339 if(float_saturation_multiplier < 0.99) |
335 int_O_DBS_bitfield |= DBS_SAT2l; | 340 int_O_DBS_bitfield |= DBS_SAT2l; |
336 if(float_saturation_multiplier > 1.3) | 341 if(float_saturation_multiplier > 1.3) |
337 int_O_DBS_bitfield |= DBS_SAT2h; | 342 int_O_DBS_bitfield |= DBS_SAT2h; |
415 temp_DBS |= DBG_C_MODE; | 420 temp_DBS |= DBG_C_MODE; |
416 if(DBG_pres_surface != pres_surface) | 421 if(DBG_pres_surface != pres_surface) |
417 temp_DBS |= DBG_C_SURF; | 422 temp_DBS |= DBG_C_SURF; |
418 | 423 |
419 if( !DBS_HE_sat && !He_ratio) | 424 if( !DBS_HE_sat && !He_ratio) |
420 for(i = 16; i < 32; i++) | 425 for(i = 0; i < NUM_COMP; i++) |
421 if(pres_tissue[i]) | 426 if(pres_tissue_He[i]) |
422 temp_DBS |= DBG_HEwoHE; | 427 temp_DBS |= DBG_HEwoHE; |
423 | 428 |
424 if( DBG_deco_gas_change != deco_gas_change[0] | 429 if( DBG_deco_gas_change != deco_gas_change[0] |
425 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0] | 430 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0] |
426 || DBG_deco_He_ratio != char_I_deco_He_ratio[0] ) | 431 || DBG_deco_He_ratio != char_I_deco_He_ratio[0] ) |
547 ////////////////////////////////////////////////////////////////////////////// | 552 ////////////////////////////////////////////////////////////////////////////// |
548 // read buhlmann tables A and B for compatriment ci | 553 // read buhlmann tables A and B for compatriment ci |
549 // | 554 // |
550 static void read_buhlmann_coefficients(void) | 555 static void read_buhlmann_coefficients(void) |
551 { | 556 { |
557 | |
552 #ifndef CROSS_COMPILE | 558 #ifndef CROSS_COMPILE |
553 // Note: we don't use far rom pointer, because the | 559 // Note: we don't use far rom pointer, because the |
554 // 24 bits is to complex, hence we have to set | 560 // 24 bits is too complex, hence we have to set |
555 // the UPPER page ourself... | 561 // the UPPER page ourself... |
556 // --> Set zero if tables are moved to lower pages ! | 562 // --> Set zero if tables are moved to lower pages ! |
557 _asm | 563 _asm |
558 movlw 1 | 564 movlw 1 |
559 movwf TBLPTRU,0 | 565 movwf TBLPTRU,0 |
560 _endasm | 566 _endasm |
561 #endif | 567 #endif |
562 | 568 |
563 assert( 0 <= ci && ci < 16 ); | 569 assert( 0 <= ci && ci < NUM_COMP ); |
564 var_N2_a = buhlmann_a[ci]; | 570 |
565 var_N2_b = buhlmann_b[ci]; | 571 // Use an interleaved array (AoS) to access coefficients with a |
566 var_He_a = (buhlmann_a+16)[ci]; | 572 // single addressing. |
567 var_He_b = (buhlmann_b+16)[ci]; | 573 { |
574 overlay rom const float* ptr = &buhlmann_ab[4*ci]; | |
575 var_N2_a = *ptr++; | |
576 var_N2_b = *ptr++; | |
577 var_He_a = *ptr++; | |
578 var_He_b = *ptr++; | |
579 } | |
568 | 580 |
569 // Check reading consistency: | 581 // Check reading consistency: |
570 if( (var_N2_a < 0.231) | 582 if( (var_N2_a < 0.231) |
571 || (var_N2_a > 1.27) | 583 || (var_N2_a > 1.27) |
572 || (var_N2_b < 0.504) | 584 || (var_N2_b < 0.504) |
594 _asm | 606 _asm |
595 movlw 1 | 607 movlw 1 |
596 movwf TBLPTRU,0 | 608 movwf TBLPTRU,0 |
597 _endasm | 609 _endasm |
598 #endif | 610 #endif |
599 assert( 0 <= ci && ci < 16 ); | 611 |
612 assert( 0 <= ci && ci < NUM_COMP ); | |
600 | 613 |
601 // Integration intervals. | 614 // Integration intervals. |
602 switch(period) | 615 switch(period) |
603 { | 616 { |
604 case 0: //---- 2 sec ----------------------------------------------------- | 617 case 0: //---- 2 sec ----------------------------------------------------- |
605 var_N2_e = e2secs[ci]; | 618 { |
606 var_He_e = (e2secs+16)[ci]; | 619 overlay rom const float* ptr = &e2secs[2*ci]; |
620 var_N2_e = *ptr++; | |
621 var_He_e = *ptr++; | |
622 } | |
607 | 623 |
608 // Check reading consistency: | 624 // Check reading consistency: |
609 if( (var_N2_e < 0.0000363) | 625 if( (var_N2_e < 0.0000363) |
610 || (var_N2_e > 0.00577) | 626 || (var_N2_e > 0.00577) |
611 || (var_He_e < 0.0000961) | 627 || (var_He_e < 0.0000961) |
614 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; | 630 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; |
615 | 631 |
616 break; | 632 break; |
617 | 633 |
618 case 1: //---- 1 min ----------------------------------------------------- | 634 case 1: //---- 1 min ----------------------------------------------------- |
619 var_N2_e = e1min[ci]; | 635 { |
620 var_He_e = (e1min+16)[ci]; | 636 overlay rom const float* ptr = &e1min[2*ci]; |
637 var_N2_e = *ptr++; | |
638 var_He_e = *ptr++; | |
639 } | |
621 | 640 |
622 // Check reading consistency: | 641 // Check reading consistency: |
623 if( (var_N2_e < 1.09E-3) | 642 if( (var_N2_e < 1.09E-3) |
624 || (var_N2_e > 0.1592) | 643 || (var_N2_e > 0.1592) |
625 || (var_He_e < 0.00288) | 644 || (var_He_e < 0.00288) |
628 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; | 647 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; |
629 | 648 |
630 break; | 649 break; |
631 | 650 |
632 case 2: //---- 10 min ---------------------------------------------------- | 651 case 2: //---- 10 min ---------------------------------------------------- |
633 var_N2_e = e10min[ci]; | 652 { |
634 var_He_e = (e10min+16)[ci]; | 653 overlay rom const float* ptr = &e10min[2*ci]; |
654 var_N2_e = *ptr++; | |
655 var_He_e = *ptr++; | |
656 } | |
635 | 657 |
636 // Check reading consistency: | 658 // Check reading consistency: |
637 if( (var_N2_e < 0.01085) | 659 if( (var_N2_e < 0.01085) |
638 || (var_N2_e > 0.82323) | 660 || (var_N2_e > 0.82323) |
639 || (var_He_e < 0.02846) | 661 || (var_He_e < 0.02846) |
647 assert(0); // Never go there... | 669 assert(0); // Never go there... |
648 } | 670 } |
649 } | 671 } |
650 | 672 |
651 ////////////////////////////////////////////////////////////////////////////// | 673 ////////////////////////////////////////////////////////////////////////////// |
652 // calc_next_decodepth_GF | 674 // calc_nextdecodepth |
653 // | 675 // |
654 // new in v.102 | 676 // new in v.102 |
655 // | 677 // |
656 // INPUT, changing during dive: | 678 // INPUT, changing during dive: |
657 // low_depth | 679 // low_depth |
831 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------ | 853 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------ |
832 { | 854 { |
833 overlay unsigned char x, y; | 855 overlay unsigned char x, y; |
834 | 856 |
835 //---- First: search the first non-null depth | 857 //---- First: search the first non-null depth |
836 for(x=31; x != 0; --x) | 858 for(x=(NUM_STOPS-1); x != 0; --x) |
837 if( internal_deco_depth[x] != 0 ) break; | 859 if( internal_deco_depth[x] != 0 ) break; |
838 | 860 |
839 //---- Second: copy to output table (in reverse order) | 861 //---- Second: copy to output table (in reverse order) |
840 for(y=0; y<32; y++, --x) | 862 for(y=0; y<NUM_STOPS; y++, --x) |
841 { | 863 { |
842 char_O_deco_depth[y] = internal_deco_depth[x]; | 864 char_O_deco_depth[y] = internal_deco_depth[x]; |
843 char_O_deco_time [y] = internal_deco_time [x]; | 865 char_O_deco_time [y] = internal_deco_time [x]; |
844 | 866 |
845 // Stop only once the last transfer is done. | 867 // Stop only once the last transfer is done. |
846 if( x == 0 ) break; | 868 if( x == 0 ) break; |
847 } | 869 } |
848 | 870 |
849 //---- Third: fill table end with null | 871 //---- Third: fill table end with null |
850 for(y++; y<32; y++) | 872 for(y++; y<NUM_STOPS; y++) |
851 { | 873 { |
852 char_O_deco_time [y] = 0; | 874 char_O_deco_time [y] = 0; |
853 char_O_deco_depth[y] = 0; | 875 char_O_deco_depth[y] = 0; |
854 } | 876 } |
855 } | 877 } |
856 else //---- Straight copy ------------------------------------------------ | 878 else //---- Straight copy ------------------------------------------------ |
857 { | 879 { |
858 overlay unsigned char x; | 880 overlay unsigned char x; |
859 | 881 |
860 for(x=0; x<32; x++) | 882 for(x=0; x<NUM_STOPS; x++) |
861 { | 883 { |
862 char_O_deco_depth[x] = internal_deco_depth[x]; | 884 char_O_deco_depth[x] = internal_deco_depth[x]; |
863 char_O_deco_time [x] = internal_deco_time [x]; | 885 char_O_deco_time [x] = internal_deco_time [x]; |
864 } | 886 } |
865 } | 887 } |
958 { | 980 { |
959 overlay unsigned char j; | 981 overlay unsigned char j; |
960 overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5); | 982 overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5); |
961 overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5); | 983 overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5); |
962 | 984 |
963 for(j=0; j<5; ++j) | 985 for(j=0; j<NUM_GAS; ++j) |
964 { | 986 { |
965 // Make sure to detect if we are already breathing some gas in | 987 // Make sure to detect if we are already breathing some gas in |
966 // the current list (happends when first gas do have a depth). | 988 // the current list (happends when first gas do have a depth). |
967 if( N2 == char_I_deco_N2_ratio[j] | 989 if( N2 == char_I_deco_N2_ratio[j] |
968 && He == char_I_deco_He_ratio[j] | 990 && He == char_I_deco_He_ratio[j] |
983 assert( depth < 130 ); | 1005 assert( depth < 130 ); |
984 | 1006 |
985 // And if I'm above the last decostop (with the 3m margin) ? | 1007 // And if I'm above the last decostop (with the 3m margin) ? |
986 if( (sim_gas_last_depth-3) > depth ) | 1008 if( (sim_gas_last_depth-3) > depth ) |
987 { | 1009 { |
988 for(j=0; j<5; ++j) | 1010 for(j=0; j<NUM_GAS; ++j) |
989 { | 1011 { |
990 // And If I am in the range of a valide stop ? | 1012 // And If I am in the range of a valide stop ? |
991 // (again, with the same 3m margin) | 1013 // (again, with the same 3m margin) |
992 if( char_I_deco_gas_change[j] | 1014 if( char_I_deco_gas_change[j] |
993 && depth <= char_I_deco_gas_change[j] | 1015 && depth <= char_I_deco_gas_change[j] |
1032 if (char_I_const_ppO2 == 0) | 1054 if (char_I_const_ppO2 == 0) |
1033 { | 1055 { |
1034 overlay unsigned char j; | 1056 overlay unsigned char j; |
1035 | 1057 |
1036 // Loop over all enabled gas, to find the deepest one, | 1058 // Loop over all enabled gas, to find the deepest one, |
1037 // above las gas, but below temp_depth_limit. | 1059 // above last used gas, but below temp_depth_limit. |
1038 for(j=0; j<5; ++j) | 1060 for(j=0; j<NUM_GAS; ++j) |
1039 { | 1061 { |
1040 // Gas not (yet) allowed ? Skip ! | 1062 // Gas not (yet) allowed ? Skip ! |
1041 if( temp_depth_limit > deco_gas_change[j] ) | 1063 if( temp_depth_limit > deco_gas_change[j] ) |
1042 continue; | 1064 continue; |
1043 | 1065 |
1090 // | 1112 // |
1091 // Output: calc_N2_ratio, calc_He_ratio | 1113 // Output: calc_N2_ratio, calc_He_ratio |
1092 // | 1114 // |
1093 static void gas_switch_set(void) | 1115 static void gas_switch_set(void) |
1094 { | 1116 { |
1095 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= 5 ); | 1117 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= NUM_GAS ); |
1096 | 1118 |
1097 if( sim_gas_last_used == 0 ) | 1119 if( sim_gas_last_used == 0 ) |
1098 { | 1120 { |
1099 calc_N2_ratio = N2_ratio; | 1121 calc_N2_ratio = N2_ratio; |
1100 calc_He_ratio = He_ratio; | 1122 calc_He_ratio = He_ratio; |
1175 | 1197 |
1176 // Kludge: the 0.0002 of 0.7902 are missing with standard air. | 1198 // Kludge: the 0.0002 of 0.7902 are missing with standard air. |
1177 N2_ratio = 0.7902; | 1199 N2_ratio = 0.7902; |
1178 pres_respiration = int_I_pres_respiration * 0.001; | 1200 pres_respiration = int_I_pres_respiration * 0.001; |
1179 | 1201 |
1180 for(ci=0; ci<16; ci++) | 1202 for(ci=0; ci<NUM_COMP; ci++) |
1181 { | 1203 { |
1182 // cycle through the 16 Bühlmann tissues | 1204 // cycle through the 16 Bühlmann tissues |
1183 overlay float p = N2_ratio * (pres_respiration - ppWater); | 1205 overlay float p = N2_ratio * (pres_respiration - ppWater); |
1184 pres_tissue[ci] = p; | 1206 pres_tissue_N2[ci] = p; |
1185 | 1207 |
1186 // cycle through the 16 Bühlmann tissues for Helium | 1208 // cycle through the 16 Bühlmann tissues for Helium |
1187 (pres_tissue+16)[ci] = 0.0; | 1209 pres_tissue_He[ci] = 0.0; |
1188 } // for 0 to 16 | 1210 } // for 0 to 15 |
1189 | 1211 |
1190 clear_deco_table(); | 1212 clear_deco_table(); |
1191 char_O_deco_status = 0; | 1213 char_O_deco_status = 0; |
1192 char_O_nullzeit = 0; | 1214 char_O_nullzeit = 0; |
1193 int_O_ascenttime = 0; | 1215 int_O_ascenttime = 0; |
1444 | 1466 |
1445 // Calc limit for surface, ie. GF_high. | 1467 // Calc limit for surface, ie. GF_high. |
1446 calc_limit(); | 1468 calc_limit(); |
1447 | 1469 |
1448 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000); | 1470 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000); |
1449 int_O_gtissue_press = (short)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000); | 1471 int_O_gtissue_press = (short)((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) * 1000); |
1450 | 1472 |
1451 // if guiding tissue can not be exposed to surface pressure immediately | 1473 // if guiding tissue can not be exposed to surface pressure immediately |
1452 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) | 1474 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) |
1453 { | 1475 { |
1454 char_O_nullzeit = 0; // deco necessary | 1476 char_O_nullzeit = 0; // deco necessary |
1614 static void calc_tissue(PARAMETER unsigned char period) | 1636 static void calc_tissue(PARAMETER unsigned char period) |
1615 { | 1637 { |
1616 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m | 1638 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m |
1617 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m | 1639 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m |
1618 | 1640 |
1619 for (ci=0;ci<16;ci++) | 1641 for (ci=0;ci<NUM_COMP;ci++) |
1620 { | 1642 { |
1621 read_buhlmann_times(period); // 2 sec or 1 min period. | 1643 read_buhlmann_times(period); // 2 sec or 1 min period. |
1622 | 1644 |
1623 // N2 | 1645 // N2 |
1624 temp_tissue = (ppN2 - pres_tissue[ci]) * var_N2_e; | 1646 temp_tissue = (ppN2 - pres_tissue_N2[ci]) * var_N2_e; |
1625 temp_tissue_safety(); | 1647 temp_tissue_safety(); |
1626 pres_tissue[ci] += temp_tissue; | 1648 pres_tissue_N2[ci] += temp_tissue; |
1627 | 1649 |
1628 // He | 1650 // He |
1629 temp_tissue = (ppHe - (pres_tissue+16)[ci]) * var_He_e; | 1651 temp_tissue = (ppHe - pres_tissue_He[ci]) * var_He_e; |
1630 temp_tissue_safety(); | 1652 temp_tissue_safety(); |
1631 (pres_tissue+16)[ci] += temp_tissue; | 1653 pres_tissue_He[ci] += temp_tissue; |
1632 } | 1654 } |
1633 } | 1655 } |
1634 | 1656 |
1635 ////////////////////////////////////////////////////////////////////////////// | 1657 ////////////////////////////////////////////////////////////////////////////// |
1636 // calc_limit | 1658 // calc_limit |
1640 static void calc_limit(void) | 1662 static void calc_limit(void) |
1641 { | 1663 { |
1642 char_O_gtissue_no = 255; | 1664 char_O_gtissue_no = 255; |
1643 calc_lead_tissue_limit = 0.0; | 1665 calc_lead_tissue_limit = 0.0; |
1644 | 1666 |
1645 for(ci=0; ci<16;ci++) | 1667 for(ci=0; ci<NUM_COMP;ci++) |
1646 { | 1668 { |
1647 overlay float N2 = pres_tissue[ci]; | 1669 overlay float N2 = pres_tissue_N2[ci]; |
1648 overlay float He = (pres_tissue+16)[ci]; | 1670 overlay float He = pres_tissue_He[ci]; |
1649 overlay float p = N2 + He; | 1671 overlay float p = N2 + He; |
1650 | 1672 |
1651 read_buhlmann_coefficients(); | 1673 read_buhlmann_coefficients(); |
1652 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; | 1674 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; |
1653 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; | 1675 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; |
1673 char_O_gtissue_no = ci; | 1695 char_O_gtissue_no = ci; |
1674 calc_lead_tissue_limit = p; | 1696 calc_lead_tissue_limit = p; |
1675 } | 1697 } |
1676 } | 1698 } |
1677 | 1699 |
1678 assert( char_O_gtissue_no < 16 ); | 1700 assert( char_O_gtissue_no < NUM_COMP ); |
1679 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); | 1701 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); |
1680 } | 1702 } |
1681 | 1703 |
1682 ////////////////////////////////////////////////////////////////////////////// | 1704 ////////////////////////////////////////////////////////////////////////////// |
1683 // calc_nullzeit | 1705 // calc_nullzeit |
1726 // | 1748 // |
1727 void backup_sim_pres_tissue(void) | 1749 void backup_sim_pres_tissue(void) |
1728 { | 1750 { |
1729 overlay unsigned char x; | 1751 overlay unsigned char x; |
1730 | 1752 |
1731 for(x = 0; x<32; x++) | 1753 for(x=0; x<NUM_COMP; x++) |
1732 sim_pres_tissue_backup[x] = sim_pres_tissue[x]; | 1754 { |
1755 sim_pres_tissue_backup_N2[x] = sim_pres_tissue_N2[x]; | |
1756 sim_pres_tissue_backup_He[x] = sim_pres_tissue_He[x]; | |
1757 } | |
1733 } | 1758 } |
1734 | 1759 |
1735 ////////////////////////////////////////////////////////////////////////////// | 1760 ////////////////////////////////////////////////////////////////////////////// |
1736 // restore_sim_pres_tissue | 1761 // restore_sim_pres_tissue |
1737 // | 1762 // |
1738 void restore_sim_pres_tissue(void) | 1763 void restore_sim_pres_tissue(void) |
1739 { | 1764 { |
1740 overlay unsigned char x; | 1765 overlay unsigned char x; |
1741 | 1766 |
1742 for(x = 0; x<32; x++) | 1767 for(x=0; x<NUM_COMP; x++) |
1743 sim_pres_tissue[x] = sim_pres_tissue_backup[x]; | 1768 { |
1769 sim_pres_tissue_N2[x] = sim_pres_tissue_backup_N2[x]; | |
1770 sim_pres_tissue_He[x] = sim_pres_tissue_backup_He[x]; | |
1771 } | |
1744 } | 1772 } |
1745 | 1773 |
1746 ////////////////////////////////////////////////////////////////////////////// | 1774 ////////////////////////////////////////////////////////////////////////////// |
1747 // calc_ascenttime | 1775 // calc_ascenttime |
1748 // | 1776 // |
1759 overlay float ascent = pres_respiration - pres_surface + 0.7; | 1787 overlay float ascent = pres_respiration - pres_surface + 0.7; |
1760 if (ascent < 0.0) | 1788 if (ascent < 0.0) |
1761 ascent = 0.0; | 1789 ascent = 0.0; |
1762 sum = (unsigned short)(ascent + 0.99); | 1790 sum = (unsigned short)(ascent + 0.99); |
1763 | 1791 |
1764 for(x=0; x<32 && internal_deco_depth[x]; x++) | 1792 for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++) |
1765 sum += (unsigned short)internal_deco_time[x]; | 1793 sum += (unsigned short)internal_deco_time[x]; |
1766 | 1794 |
1767 if( char_O_deco_status == 1 ) | 1795 if( char_O_deco_status == 1 ) |
1768 int_O_ascenttime = sum; | 1796 int_O_ascenttime = sum; |
1769 else | 1797 else |
1778 void update_startvalues(void) | 1806 void update_startvalues(void) |
1779 { | 1807 { |
1780 overlay unsigned char x; | 1808 overlay unsigned char x; |
1781 | 1809 |
1782 // Start ascent simulation with current tissue partial pressures. | 1810 // Start ascent simulation with current tissue partial pressures. |
1783 for (x = 0;x<16;x++) | 1811 for(x=0; x<NUM_COMP; x++) |
1784 { | 1812 { |
1785 sim_pres_tissue[x] = pres_tissue[x]; | 1813 sim_pres_tissue_N2[x] = pres_tissue_N2[x]; |
1786 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; | 1814 sim_pres_tissue_He[x] = pres_tissue_He[x]; |
1787 } | 1815 } |
1788 | 1816 |
1789 // No leading tissue (yet) for this ascent simulation. | 1817 // No leading tissue (yet) for this ascent simulation. |
1790 sim_lead_tissue_limit = 0.0; | 1818 sim_lead_tissue_limit = 0.0; |
1791 sim_lead_tissue_no = 255; | 1819 sim_lead_tissue_no = 255; |
1802 static void sim_tissue(PARAMETER unsigned char period) | 1830 static void sim_tissue(PARAMETER unsigned char period) |
1803 { | 1831 { |
1804 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m | 1832 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m |
1805 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m | 1833 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m |
1806 | 1834 |
1807 for(ci=0; ci<16; ci++) | 1835 for(ci=0; ci<NUM_COMP; ci++) |
1808 { | 1836 { |
1809 read_buhlmann_times(period); // 1 or 10 minute(s) interval | 1837 read_buhlmann_times(period); // 1 or 10 minute(s) interval |
1810 | 1838 |
1811 // N2 | 1839 // N2 |
1812 temp_tissue = (ppN2 - sim_pres_tissue[ci]) * var_N2_e; | 1840 temp_tissue = (ppN2 - sim_pres_tissue_N2[ci]) * var_N2_e; |
1813 temp_tissue_safety(); | 1841 temp_tissue_safety(); |
1814 sim_pres_tissue[ci] += temp_tissue; | 1842 sim_pres_tissue_N2[ci] += temp_tissue; |
1815 | 1843 |
1816 // He | 1844 // He |
1817 temp_tissue = (ppHe - (sim_pres_tissue+16)[ci]) * var_He_e; | 1845 temp_tissue = (ppHe - sim_pres_tissue_He[ci]) * var_He_e; |
1818 temp_tissue_safety(); | 1846 temp_tissue_safety(); |
1819 (sim_pres_tissue+16)[ci] += temp_tissue; | 1847 sim_pres_tissue_He[ci] += temp_tissue; |
1820 } | 1848 } |
1821 } | 1849 } |
1822 | 1850 |
1823 ////////////////////////////////////////////////////////////////////////////// | 1851 ////////////////////////////////////////////////////////////////////////////// |
1824 // sim_limit() | 1852 // sim_limit() |
1833 assert( 0.0 < GF_current && GF_current <= 1.0f); | 1861 assert( 0.0 < GF_current && GF_current <= 1.0f); |
1834 | 1862 |
1835 sim_lead_tissue_limit = 0.0; | 1863 sim_lead_tissue_limit = 0.0; |
1836 sim_lead_tissue_no = 0; // If no one is critic, keep first tissue. | 1864 sim_lead_tissue_no = 0; // If no one is critic, keep first tissue. |
1837 | 1865 |
1838 for(ci=0; ci<16; ci++) | 1866 for(ci=0; ci<NUM_COMP; ci++) |
1839 { | 1867 { |
1840 overlay float N2 = sim_pres_tissue[ci]; | 1868 overlay float N2 = sim_pres_tissue_N2[ci]; |
1841 overlay float He = (sim_pres_tissue+16)[ci]; | 1869 overlay float He = sim_pres_tissue_He[ci]; |
1842 overlay float p = N2 + He; | 1870 overlay float p = N2 + He; |
1843 | 1871 |
1844 read_buhlmann_coefficients(); | 1872 read_buhlmann_coefficients(); |
1845 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; | 1873 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; |
1846 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; | 1874 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; |
1862 sim_lead_tissue_no = ci; | 1890 sim_lead_tissue_no = ci; |
1863 sim_lead_tissue_limit = p; | 1891 sim_lead_tissue_limit = p; |
1864 } | 1892 } |
1865 } // for ci | 1893 } // for ci |
1866 | 1894 |
1867 assert( sim_lead_tissue_no < 16 ); | 1895 assert( sim_lead_tissue_no < NUM_COMP ); |
1868 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 ); | 1896 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 ); |
1869 } | 1897 } |
1870 | 1898 |
1871 ////////////////////////////////////////////////////////////////////////////// | 1899 ////////////////////////////////////////////////////////////////////////////// |
1872 // clear_deco_table | 1900 // clear_deco_table |
1875 // | 1903 // |
1876 static void clear_deco_table(void) | 1904 static void clear_deco_table(void) |
1877 { | 1905 { |
1878 overlay unsigned char x; | 1906 overlay unsigned char x; |
1879 | 1907 |
1880 for(x=0; x<32; ++x) | 1908 for(x=0; x<NUM_STOPS; ++x) |
1881 { | 1909 { |
1882 internal_deco_time [x] = 0; | 1910 internal_deco_time [x] = 0; |
1883 internal_deco_depth[x] = 0; | 1911 internal_deco_depth[x] = 0; |
1884 } | 1912 } |
1885 } | 1913 } |
1899 { | 1927 { |
1900 overlay unsigned char x; | 1928 overlay unsigned char x; |
1901 assert( temp_depth_limit < 128 ); // Can't be negativ (overflown). | 1929 assert( temp_depth_limit < 128 ); // Can't be negativ (overflown). |
1902 assert( temp_depth_limit > 0 ); // No stop at surface... | 1930 assert( temp_depth_limit > 0 ); // No stop at surface... |
1903 | 1931 |
1904 for(x=0; x<32; ++x) | 1932 for(x=0; x<NUM_STOPS; ++x) |
1905 { | 1933 { |
1906 // Make sure deco-stops are recorded in order: | 1934 // Make sure deco-stops are recorded in order: |
1907 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) ); | 1935 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) ); |
1908 | 1936 |
1909 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit ) | 1937 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit ) |
1940 // new code in v.102 | 1968 // new code in v.102 |
1941 // | 1969 // |
1942 static void calc_gradient_factor(void) | 1970 static void calc_gradient_factor(void) |
1943 { | 1971 { |
1944 overlay float gf; | 1972 overlay float gf; |
1945 overlay float N2 = pres_tissue[char_O_gtissue_no]; | 1973 overlay float N2 = pres_tissue_N2[char_O_gtissue_no]; |
1946 overlay float He = (pres_tissue+16)[char_O_gtissue_no]; | 1974 overlay float He = pres_tissue_He[char_O_gtissue_no]; |
1947 | 1975 |
1948 assert( char_O_gtissue_no < 16 ); | 1976 assert( char_O_gtissue_no < NUM_COMP ); |
1949 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); | 1977 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); |
1950 | 1978 |
1951 // tissue > respiration (currently off-gasing) | 1979 // tissue > respiration (currently off-gasing) |
1952 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium. | 1980 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium. |
1953 // GF = 100% when respiration == limit. | 1981 // GF = 100% when respiration == limit. |
2016 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier | 2044 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier |
2017 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31] | 2045 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31] |
2018 // | 2046 // |
2019 void deco_calc_desaturation_time(void) | 2047 void deco_calc_desaturation_time(void) |
2020 { | 2048 { |
2049 overlay rom const float *ptr; | |
2050 | |
2021 RESET_C_STACK | 2051 RESET_C_STACK |
2022 | 2052 |
2023 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); | 2053 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); |
2024 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); | 2054 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); |
2025 | 2055 |
2038 pres_surface = int_I_pres_surface * 0.001; | 2068 pres_surface = int_I_pres_surface * 0.001; |
2039 ppN2 = N2_ratio * (pres_surface - ppWater); | 2069 ppN2 = N2_ratio * (pres_surface - ppWater); |
2040 int_O_desaturation_time = 0; | 2070 int_O_desaturation_time = 0; |
2041 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 2071 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) |
2042 | 2072 |
2043 for (ci=0;ci<16;ci++) | 2073 ptr = &buhlmann_ht[0]; |
2044 { | 2074 for(ci=0; ci<NUM_COMP; ci++) |
2075 { | |
2076 overlay float var_N2_halftime = *ptr++; | |
2077 overlay float var_He_halftime = *ptr++; | |
2045 overlay unsigned short desat_time; // For a particular compartiment, in min. | 2078 overlay unsigned short desat_time; // For a particular compartiment, in min. |
2046 overlay float temp1; | 2079 overlay float temp1; |
2047 overlay float temp2; | 2080 overlay float temp2; |
2048 overlay float temp3; | 2081 overlay float temp3; |
2049 overlay float temp4; | 2082 overlay float temp4; |
2050 | 2083 |
2084 assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 ); | |
2085 assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 ); | |
2086 | |
2051 // saturation_time (for flight) and N2_saturation in multiples of halftime | 2087 // saturation_time (for flight) and N2_saturation in multiples of halftime |
2052 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time ) | 2088 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time ) |
2053 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time ) | 2089 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time ) |
2054 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations | 2090 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations |
2055 // N2 | 2091 // N2 |
2056 temp1 = 1.05 * ppN2 - pres_tissue[ci]; | 2092 temp1 = 1.05 * ppN2 - pres_tissue_N2[ci]; |
2057 temp2 = ppN2 - pres_tissue[ci]; | 2093 temp2 = ppN2 - pres_tissue_N2[ci]; |
2058 if (temp2 >= 0.0) | 2094 if (temp2 >= 0.0) |
2059 { | 2095 { |
2060 temp1 = 0.0; | 2096 temp1 = 0.0; |
2061 temp2 = 0.0; | 2097 temp2 = 0.0; |
2062 } | 2098 } |
2063 else | 2099 else |
2064 temp1 = temp1 / temp2; | 2100 temp1 = temp1 / temp2; |
2065 if( 0.0 < temp1 && temp1 < 1.0 ) | 2101 if( 0.0 < temp1 && temp1 < 1.0 ) |
2066 { | 2102 { |
2067 overlay float var_N2_halftime = buhlmann_ht[ci]; | |
2068 assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 ); | |
2069 | |
2070 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. | 2103 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. |
2071 // minus because log is negative. | 2104 // minus because log is negative. |
2072 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary. | 2105 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary. |
2073 temp2 = var_N2_halftime * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 5 percent) , new in v.101: float_desaturation_multiplier | 2106 temp2 = var_N2_halftime * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 5 percent) , new in v.101: float_desaturation_multiplier |
2074 | 2107 |
2078 temp1 = 0.0; | 2111 temp1 = 0.0; |
2079 temp2 = 0.0; | 2112 temp2 = 0.0; |
2080 } | 2113 } |
2081 | 2114 |
2082 // He | 2115 // He |
2083 temp3 = 0.1 - (pres_tissue+16)[ci]; | 2116 temp3 = 0.1 - pres_tissue_He[ci]; |
2084 if (temp3 >= 0.0) | 2117 if (temp3 >= 0.0) |
2085 { | 2118 { |
2086 temp3 = 0.0; | 2119 temp3 = 0.0; |
2087 temp4 = 0.0; | 2120 temp4 = 0.0; |
2088 } | 2121 } |
2089 else | 2122 else |
2090 temp3 = - temp3 / (pres_tissue+16)[ci]; | 2123 temp3 = - temp3 / pres_tissue_He[ci]; |
2091 if( 0.0 < temp3 && temp3 < 1.0 ) | 2124 if( 0.0 < temp3 && temp3 < 1.0 ) |
2092 { | 2125 { |
2093 overlay float var_He_halftime = (buhlmann_ht+16)[ci]; | |
2094 assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 ); | |
2095 | |
2096 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary. | 2126 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary. |
2097 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. | 2127 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. |
2098 // minus because log is negative | 2128 // minus because log is negative |
2099 temp4 = var_He_halftime * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier | 2129 temp4 = var_He_halftime * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier |
2100 } | 2130 } |
2112 | 2142 |
2113 if(desat_time > int_O_desaturation_time) | 2143 if(desat_time > int_O_desaturation_time) |
2114 int_O_desaturation_time = desat_time; | 2144 int_O_desaturation_time = desat_time; |
2115 | 2145 |
2116 // N2 saturation in multiples of halftime for display purposes | 2146 // N2 saturation in multiples of halftime for display purposes |
2117 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 | 2147 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 |
2118 temp2 = temp2 + 80.0; // set center | 2148 temp2 = temp2 + 80.0; // set center |
2119 if (temp2 < 0.0) | 2149 if (temp2 < 0.0) |
2120 temp2 = 0.0; | 2150 temp2 = 0.0; |
2121 if (temp2 > 255.0) | 2151 if (temp2 > 255.0) |
2122 temp2 = 255.0; | 2152 temp2 = 255.0; |
2123 char_O_tissue_saturation[ci] = (char)temp2; | 2153 char_O_tissue_N2_saturation[ci] = (char)temp2; |
2124 | 2154 |
2125 // He saturation in multiples of halftime for display purposes | 2155 // He saturation in multiples of halftime for display purposes |
2126 temp4 = temp3 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 | 2156 temp4 = temp3 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 |
2127 temp4 = temp4 + 80.0; // set center | 2157 temp4 = temp4 + 80.0; // set center |
2128 if (temp4 < 0.0) | 2158 if (temp4 < 0.0) |
2129 temp4 = 0.0; | 2159 temp4 = 0.0; |
2130 if (temp4 > 255.0) | 2160 if (temp4 > 255.0) |
2131 temp4 = 255.0; | 2161 temp4 = 255.0; |
2132 (char_O_tissue_saturation+16)[ci] = (char)temp4; | 2162 char_O_tissue_He_saturation[ci] = (char)temp4; |
2133 } // for | 2163 } // for |
2134 } | 2164 } |
2135 | 2165 |
2136 ////////////////////////////////////////////////////////////////////////////// | 2166 ////////////////////////////////////////////////////////////////////////////// |
2137 // calc_wo_deco_step_1_min | 2167 // calc_wo_deco_step_1_min |
2159 ppN2 = N2_ratio * (pres_respiration - ppWater); // ppWater is the extra pressure in the body | 2189 ppN2 = N2_ratio * (pres_respiration - ppWater); // ppWater is the extra pressure in the body |
2160 ppHe = 0.0; | 2190 ppHe = 0.0; |
2161 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 2191 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) |
2162 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; | 2192 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; |
2163 | 2193 |
2164 calc_tissue(1); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 2194 calc_tissue(1); // update the pressure in the tissues N2/He in accordance with the new ambient pressure |
2165 | 2195 |
2166 clear_deco_table(); | 2196 clear_deco_table(); |
2167 char_O_deco_status = 3; // surface new in v.102 : stays in surface state. | 2197 char_O_deco_status = 3; // surface new in v.102 : stays in surface state. |
2168 char_O_nullzeit = 0; | 2198 char_O_nullzeit = 0; |
2169 int_O_ascenttime = 0; | 2199 int_O_ascenttime = 0; |
2404 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0) or bar/min. | 2434 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0) or bar/min. |
2405 // Output: int_O_gas_volumes[0..4] in litters * 0.1 | 2435 // Output: int_O_gas_volumes[0..4] in litters * 0.1 |
2406 // | 2436 // |
2407 void deco_gas_volumes(void) | 2437 void deco_gas_volumes(void) |
2408 { | 2438 { |
2409 overlay float volumes[5]; | 2439 overlay float volumes[NUM_GAS]; |
2410 overlay float bottom_usage, ascent_usage; | 2440 overlay float bottom_usage, ascent_usage; |
2411 overlay unsigned char i, deepest_first; | 2441 overlay unsigned char i, deepest_first; |
2412 overlay unsigned char gas; | 2442 overlay unsigned char gas; |
2413 RESET_C_STACK | 2443 RESET_C_STACK |
2414 | 2444 |
2415 //---- initialize with bottom consumption -------------------------------- | 2445 //---- initialize with bottom consumption -------------------------------- |
2416 for(i=0; i<5; ++i) // Nothing yet... | 2446 for(i=0; i<NUM_GAS; ++i) // Nothing yet... |
2417 volumes[i] = 0.0; | 2447 volumes[i] = 0.0; |
2418 | 2448 |
2419 assert(1 <= char_I_first_gas && char_I_first_gas <= 5); | 2449 assert(1 <= char_I_first_gas && char_I_first_gas <= NUM_GAS); |
2420 gas = char_I_first_gas - 1; | 2450 gas = char_I_first_gas - 1; |
2421 | 2451 |
2422 bottom_usage = read_custom_function(56) * 0.1; | 2452 bottom_usage = read_custom_function(56) * 0.1; |
2423 if( bottom_usage > 0.0 ) | 2453 if( bottom_usage > 0.0 ) |
2424 volumes[gas] | 2454 volumes[gas] |
2444 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min) | 2474 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min) |
2445 * ascent_usage; // Consumption ( xxx / min @ 1 bar) | 2475 * ascent_usage; // Consumption ( xxx / min @ 1 bar) |
2446 else | 2476 else |
2447 volumes[gas] = 65535.0; | 2477 volumes[gas] = 65535.0; |
2448 | 2478 |
2449 for(i=0; i<32; ++i) | 2479 for(i=0; i<NUM_STOPS; ++i) |
2450 { | 2480 { |
2451 overlay unsigned char j; | 2481 overlay unsigned char j; |
2452 overlay unsigned char depth, time, ascent; | 2482 overlay unsigned char depth, time, ascent; |
2453 | 2483 |
2454 // Manage stops in reverse order (CF#54) | 2484 // Manage stops in reverse order (CF#54) |
2470 if( i < 31 ) | 2500 if( i < 31 ) |
2471 ascent -= char_O_deco_depth[30-i] & 0x7F; | 2501 ascent -= char_O_deco_depth[30-i] & 0x7F; |
2472 } | 2502 } |
2473 | 2503 |
2474 // Gas switch depth ? | 2504 // Gas switch depth ? |
2475 for(j=0; j<5; ++j) | 2505 for(j=0; j<NUM_GAS; ++j) |
2476 { | 2506 { |
2477 if( depth <= char_I_deco_gas_change[j] ) | 2507 if( depth <= char_I_deco_gas_change[j] ) |
2478 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) ) | 2508 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) ) |
2479 gas = j; | 2509 gas = j; |
2480 } | 2510 } |
2492 else | 2522 else |
2493 volumes[gas] = 65535.0; | 2523 volumes[gas] = 65535.0; |
2494 } | 2524 } |
2495 | 2525 |
2496 //---- convert results for the ASM interface ----------------------------- | 2526 //---- convert results for the ASM interface ----------------------------- |
2497 for(i=0; i<5; ++i) | 2527 for(i=0; i<NUM_GAS; ++i) |
2498 if( volumes[i] > 6553.4 ) | 2528 if( volumes[i] > 6553.4 ) |
2499 int_O_gas_volumes[i] = 65535; | 2529 int_O_gas_volumes[i] = 65535; |
2500 else | 2530 else |
2501 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5); | 2531 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5); |
2502 } | 2532 } |
2507 { | 2537 { |
2508 overlay unsigned char x; | 2538 overlay unsigned char x; |
2509 RESET_C_STACK | 2539 RESET_C_STACK |
2510 | 2540 |
2511 cns_vault = CNS_fraction; | 2541 cns_vault = CNS_fraction; |
2512 for (x=0;x<32;x++) | 2542 for (x=0;x<NUM_COMP;x++) |
2513 pres_tissue_vault[x] = pres_tissue[x]; | 2543 { |
2544 pres_tissue_N2_vault[x] = pres_tissue_N2[x]; | |
2545 pres_tissue_He_vault[x] = pres_tissue_He[x]; | |
2546 } | |
2514 } | 2547 } |
2515 | 2548 |
2516 void deco_pull_tissues_from_vault(void) | 2549 void deco_pull_tissues_from_vault(void) |
2517 { | 2550 { |
2518 overlay unsigned char x; | 2551 overlay unsigned char x; |
2519 RESET_C_STACK | 2552 RESET_C_STACK |
2520 | 2553 |
2521 for (x=0;x<32;x++) | 2554 for (x=0; x<NUM_COMP; x++) |
2522 pres_tissue[x] = pres_tissue_vault[x]; | 2555 { |
2556 pres_tissue_N2[x] = pres_tissue_N2_vault[x]; | |
2557 pres_tissue_He[x] = pres_tissue_He_vault[x]; | |
2558 } | |
2523 | 2559 |
2524 // Restore both CNS variable, too. | 2560 // Restore both CNS variable, too. |
2525 CNS_fraction = cns_vault; | 2561 CNS_fraction = cns_vault; |
2526 char_O_CNS_fraction = (char)(CNS_fraction * 100.0 + 0.5); | 2562 char_O_CNS_fraction = (char)(CNS_fraction * 100.0 + 0.5); |
2527 } | 2563 } |