Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 338:b75564fb3d4b
Optimizing access to B?hlmann coefficient (speed).
Define number of compartiments, stops and gases.
author | JeanDo |
---|---|
date | Tue, 17 May 2011 15:56:09 +0200 |
parents | 4ccdc72ec0e5 |
children | cb77d1fa4535 |
comparison
equal
deleted
inserted
replaced
334:4ccdc72ec0e5 | 338:b75564fb3d4b |
---|---|
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_vault[2*NUM_COMP]; |
171 | 172 |
172 //---- Bank 5 parameters ----------------------------------------------------- | 173 //---- Bank 5 parameters ----------------------------------------------------- |
173 #pragma udata bank5=0x500 | 174 #pragma udata bank5=0x500 |
174 | 175 |
175 static unsigned char ci; | 176 static unsigned char ci; |
186 static float var_He_a; // Bühlmann a, for current He tissue. | 187 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. | 188 static float var_He_b; // Bühlmann b, for current He tissue. |
188 static float var_N2_e; // Exposition, for current N2 tissue. | 189 static float var_N2_e; // Exposition, for current N2 tissue. |
189 static float var_He_e; // Exposition, for current He tissue. | 190 static float var_He_e; // Exposition, for current He tissue. |
190 | 191 |
191 static float pres_diluent; // new in v.101 | 192 static float pres_diluent; // new in v.101 |
192 static float const_ppO2; // new in v.101 | 193 static float const_ppO2; // new in v.101 |
193 | 194 |
194 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch. | 195 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. | 196 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]. | 197 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. | 198 static unsigned short sim_dive_mins; // Simulated dive time. |
198 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. | 199 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. |
199 static float calc_He_ratio; // Simulated (switched) helium ratio. | 200 static float calc_He_ratio; // Simulated (switched) helium ratio. |
200 static float CNS_fraction; // new in v.101 | 201 static float CNS_fraction; // new in v.101 |
201 static float float_saturation_multiplier; // new in v.101 | 202 static float float_saturation_multiplier; // new in v.101 |
202 static float float_desaturation_multiplier; // new in v.101 | 203 static float float_desaturation_multiplier; // new in v.101 |
203 static float float_deco_distance; // new in v.101 | 204 static float float_deco_distance; // new in v.101 |
204 static char flag_in_divemode; // new in v.108 | 205 static char flag_in_divemode; // new in v.108 |
205 | 206 |
206 static unsigned char deco_gas_change[5]; // new in v.109 | 207 static unsigned char deco_gas_change[NUM_GAS]; // new in v.109 |
207 | 208 |
208 //---- Bank 6 parameters ----------------------------------------------------- | 209 //---- Bank 6 parameters ----------------------------------------------------- |
209 #pragma udata bank6=0x600 | 210 #pragma udata bank6=0x600 |
210 | 211 |
211 float pres_tissue[32]; | 212 float pres_tissue[2*NUM_COMP]; |
212 | 213 |
213 //---- Bank 7 parameters ----------------------------------------------------- | 214 //---- Bank 7 parameters ----------------------------------------------------- |
214 #pragma udata bank7=0x700 | 215 #pragma udata bank7=0x700 |
215 | 216 |
216 float sim_pres_tissue[32]; // 32 floats = 128 bytes. | 217 float sim_pres_tissue[2*NUM_COMP]; // 32 floats = 128 bytes. |
217 static float sim_pres_tissue_backup[32]; | 218 static float sim_pres_tissue_backup[2*NUM_COMP]; |
218 | 219 |
219 //---- Bank 8 parameters ----------------------------------------------------- | 220 //---- Bank 8 parameters ----------------------------------------------------- |
220 #pragma udata bank8=0x800 | 221 #pragma udata bank8=0x800 |
221 | 222 |
222 static char md_pi_subst[256]; | 223 static char md_pi_subst[256]; |
326 //---- Setup some error (?) conditions ----------------------------------- | 327 //---- Setup some error (?) conditions ----------------------------------- |
327 if(char_I_deco_model) | 328 if(char_I_deco_model) |
328 int_O_DBS_bitfield |= DBS_mode; | 329 int_O_DBS_bitfield |= DBS_mode; |
329 if(const_ppO2) | 330 if(const_ppO2) |
330 int_O_DBS_bitfield |= DBS_ppO2; | 331 int_O_DBS_bitfield |= DBS_ppO2; |
331 for(i = 16; i < 32; i++) | 332 for(i = NUM_COMP; i < 2*NUM_COMP; i++) |
332 if(pres_tissue[i]) | 333 if(pres_tissue[i]) |
333 int_O_DBS_bitfield |= DBS_HE_sat; | 334 int_O_DBS_bitfield |= DBS_HE_sat; |
334 if(float_saturation_multiplier < 0.99) | 335 if(float_saturation_multiplier < 0.99) |
335 int_O_DBS_bitfield |= DBS_SAT2l; | 336 int_O_DBS_bitfield |= DBS_SAT2l; |
336 if(float_saturation_multiplier > 1.3) | 337 if(float_saturation_multiplier > 1.3) |
415 temp_DBS |= DBG_C_MODE; | 416 temp_DBS |= DBG_C_MODE; |
416 if(DBG_pres_surface != pres_surface) | 417 if(DBG_pres_surface != pres_surface) |
417 temp_DBS |= DBG_C_SURF; | 418 temp_DBS |= DBG_C_SURF; |
418 | 419 |
419 if( !DBS_HE_sat && !He_ratio) | 420 if( !DBS_HE_sat && !He_ratio) |
420 for(i = 16; i < 32; i++) | 421 for(i = NUM_COMP; i < 2*NUM_COMP; i++) |
421 if(pres_tissue[i]) | 422 if(pres_tissue[i]) |
422 temp_DBS |= DBG_HEwoHE; | 423 temp_DBS |= DBG_HEwoHE; |
423 | 424 |
424 if( DBG_deco_gas_change != deco_gas_change[0] | 425 if( DBG_deco_gas_change != deco_gas_change[0] |
425 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0] | 426 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0] |
547 ////////////////////////////////////////////////////////////////////////////// | 548 ////////////////////////////////////////////////////////////////////////////// |
548 // read buhlmann tables A and B for compatriment ci | 549 // read buhlmann tables A and B for compatriment ci |
549 // | 550 // |
550 static void read_buhlmann_coefficients(void) | 551 static void read_buhlmann_coefficients(void) |
551 { | 552 { |
553 | |
552 #ifndef CROSS_COMPILE | 554 #ifndef CROSS_COMPILE |
553 // Note: we don't use far rom pointer, because the | 555 // Note: we don't use far rom pointer, because the |
554 // 24 bits is to complex, hence we have to set | 556 // 24 bits is too complex, hence we have to set |
555 // the UPPER page ourself... | 557 // the UPPER page ourself... |
556 // --> Set zero if tables are moved to lower pages ! | 558 // --> Set zero if tables are moved to lower pages ! |
557 _asm | 559 _asm |
558 movlw 1 | 560 movlw 1 |
559 movwf TBLPTRU,0 | 561 movwf TBLPTRU,0 |
560 _endasm | 562 _endasm |
561 #endif | 563 #endif |
562 | 564 |
563 assert( 0 <= ci && ci < 16 ); | 565 assert( 0 <= ci && ci < NUM_COMP ); |
564 var_N2_a = buhlmann_a[ci]; | 566 |
565 var_N2_b = buhlmann_b[ci]; | 567 // Use an interleaved array (AoS) to access coefficients with a |
566 var_He_a = (buhlmann_a+16)[ci]; | 568 // single addressing. |
567 var_He_b = (buhlmann_b+16)[ci]; | 569 { |
570 overlay rom const float* ptr = &buhlmann_ab[4*ci]; | |
571 var_N2_a = *ptr++; | |
572 var_N2_b = *ptr++; | |
573 var_He_a = *ptr++; | |
574 var_He_b = *ptr++; | |
575 } | |
568 | 576 |
569 // Check reading consistency: | 577 // Check reading consistency: |
570 if( (var_N2_a < 0.231) | 578 if( (var_N2_a < 0.231) |
571 || (var_N2_a > 1.27) | 579 || (var_N2_a > 1.27) |
572 || (var_N2_b < 0.504) | 580 || (var_N2_b < 0.504) |
594 _asm | 602 _asm |
595 movlw 1 | 603 movlw 1 |
596 movwf TBLPTRU,0 | 604 movwf TBLPTRU,0 |
597 _endasm | 605 _endasm |
598 #endif | 606 #endif |
599 assert( 0 <= ci && ci < 16 ); | 607 |
608 assert( 0 <= ci && ci < NUM_COMP ); | |
600 | 609 |
601 // Integration intervals. | 610 // Integration intervals. |
602 switch(period) | 611 switch(period) |
603 { | 612 { |
604 case 0: //---- 2 sec ----------------------------------------------------- | 613 case 0: //---- 2 sec ----------------------------------------------------- |
605 var_N2_e = e2secs[ci]; | 614 { |
606 var_He_e = (e2secs+16)[ci]; | 615 overlay rom const float* ptr = &e2secs[2*ci]; |
616 var_N2_e = *ptr++; | |
617 var_He_e = *ptr++; | |
618 } | |
607 | 619 |
608 // Check reading consistency: | 620 // Check reading consistency: |
609 if( (var_N2_e < 0.0000363) | 621 if( (var_N2_e < 0.0000363) |
610 || (var_N2_e > 0.00577) | 622 || (var_N2_e > 0.00577) |
611 || (var_He_e < 0.0000961) | 623 || (var_He_e < 0.0000961) |
614 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; | 626 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; |
615 | 627 |
616 break; | 628 break; |
617 | 629 |
618 case 1: //---- 1 min ----------------------------------------------------- | 630 case 1: //---- 1 min ----------------------------------------------------- |
619 var_N2_e = e1min[ci]; | 631 { |
620 var_He_e = (e1min+16)[ci]; | 632 overlay rom const float* ptr = &e1min[2*ci]; |
633 var_N2_e = *ptr++; | |
634 var_He_e = *ptr++; | |
635 } | |
621 | 636 |
622 // Check reading consistency: | 637 // Check reading consistency: |
623 if( (var_N2_e < 1.09E-3) | 638 if( (var_N2_e < 1.09E-3) |
624 || (var_N2_e > 0.1592) | 639 || (var_N2_e > 0.1592) |
625 || (var_He_e < 0.00288) | 640 || (var_He_e < 0.00288) |
628 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; | 643 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; |
629 | 644 |
630 break; | 645 break; |
631 | 646 |
632 case 2: //---- 10 min ---------------------------------------------------- | 647 case 2: //---- 10 min ---------------------------------------------------- |
633 var_N2_e = e10min[ci]; | 648 { |
634 var_He_e = (e10min+16)[ci]; | 649 overlay rom const float* ptr = &e10min[2*ci]; |
650 var_N2_e = *ptr++; | |
651 var_He_e = *ptr++; | |
652 } | |
635 | 653 |
636 // Check reading consistency: | 654 // Check reading consistency: |
637 if( (var_N2_e < 0.01085) | 655 if( (var_N2_e < 0.01085) |
638 || (var_N2_e > 0.82323) | 656 || (var_N2_e > 0.82323) |
639 || (var_He_e < 0.02846) | 657 || (var_He_e < 0.02846) |
835 //---- First: search the first non-null depth | 853 //---- First: search the first non-null depth |
836 for(x=31; x != 0; --x) | 854 for(x=31; x != 0; --x) |
837 if( internal_deco_depth[x] != 0 ) break; | 855 if( internal_deco_depth[x] != 0 ) break; |
838 | 856 |
839 //---- Second: copy to output table (in reverse order) | 857 //---- Second: copy to output table (in reverse order) |
840 for(y=0; y<32; y++, --x) | 858 for(y=0; y<NUM_STOPS; y++, --x) |
841 { | 859 { |
842 char_O_deco_depth[y] = internal_deco_depth[x]; | 860 char_O_deco_depth[y] = internal_deco_depth[x]; |
843 char_O_deco_time [y] = internal_deco_time [x]; | 861 char_O_deco_time [y] = internal_deco_time [x]; |
844 | 862 |
845 // Stop only once the last transfer is done. | 863 // Stop only once the last transfer is done. |
846 if( x == 0 ) break; | 864 if( x == 0 ) break; |
847 } | 865 } |
848 | 866 |
849 //---- Third: fill table end with null | 867 //---- Third: fill table end with null |
850 for(y++; y<32; y++) | 868 for(y++; y<2*NUM_COMP; y++) |
851 { | 869 { |
852 char_O_deco_time [y] = 0; | 870 char_O_deco_time [y] = 0; |
853 char_O_deco_depth[y] = 0; | 871 char_O_deco_depth[y] = 0; |
854 } | 872 } |
855 } | 873 } |
856 else //---- Straight copy ------------------------------------------------ | 874 else //---- Straight copy ------------------------------------------------ |
857 { | 875 { |
858 overlay unsigned char x; | 876 overlay unsigned char x; |
859 | 877 |
860 for(x=0; x<32; x++) | 878 for(x=0; x<2*NUM_COMP; x++) |
861 { | 879 { |
862 char_O_deco_depth[x] = internal_deco_depth[x]; | 880 char_O_deco_depth[x] = internal_deco_depth[x]; |
863 char_O_deco_time [x] = internal_deco_time [x]; | 881 char_O_deco_time [x] = internal_deco_time [x]; |
864 } | 882 } |
865 } | 883 } |
958 { | 976 { |
959 overlay unsigned char j; | 977 overlay unsigned char j; |
960 overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5); | 978 overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5); |
961 overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5); | 979 overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5); |
962 | 980 |
963 for(j=0; j<5; ++j) | 981 for(j=0; j<NUM_GAS; ++j) |
964 { | 982 { |
965 // Make sure to detect if we are already breathing some gas in | 983 // Make sure to detect if we are already breathing some gas in |
966 // the current list (happends when first gas do have a depth). | 984 // the current list (happends when first gas do have a depth). |
967 if( N2 == char_I_deco_N2_ratio[j] | 985 if( N2 == char_I_deco_N2_ratio[j] |
968 && He == char_I_deco_He_ratio[j] | 986 && He == char_I_deco_He_ratio[j] |
983 assert( depth < 130 ); | 1001 assert( depth < 130 ); |
984 | 1002 |
985 // And if I'm above the last decostop (with the 3m margin) ? | 1003 // And if I'm above the last decostop (with the 3m margin) ? |
986 if( (sim_gas_last_depth-3) > depth ) | 1004 if( (sim_gas_last_depth-3) > depth ) |
987 { | 1005 { |
988 for(j=0; j<5; ++j) | 1006 for(j=0; j<NUM_GAS; ++j) |
989 { | 1007 { |
990 // And If I am in the range of a valide stop ? | 1008 // And If I am in the range of a valide stop ? |
991 // (again, with the same 3m margin) | 1009 // (again, with the same 3m margin) |
992 if( char_I_deco_gas_change[j] | 1010 if( char_I_deco_gas_change[j] |
993 && depth <= char_I_deco_gas_change[j] | 1011 && depth <= char_I_deco_gas_change[j] |
1033 { | 1051 { |
1034 overlay unsigned char j; | 1052 overlay unsigned char j; |
1035 | 1053 |
1036 // Loop over all enabled gas, to find the deepest one, | 1054 // Loop over all enabled gas, to find the deepest one, |
1037 // above las gas, but below temp_depth_limit. | 1055 // above las gas, but below temp_depth_limit. |
1038 for(j=0; j<5; ++j) | 1056 for(j=0; j<NUM_GAS; ++j) |
1039 { | 1057 { |
1040 // Gas not (yet) allowed ? Skip ! | 1058 // Gas not (yet) allowed ? Skip ! |
1041 if( temp_depth_limit > deco_gas_change[j] ) | 1059 if( temp_depth_limit > deco_gas_change[j] ) |
1042 continue; | 1060 continue; |
1043 | 1061 |
1090 // | 1108 // |
1091 // Output: calc_N2_ratio, calc_He_ratio | 1109 // Output: calc_N2_ratio, calc_He_ratio |
1092 // | 1110 // |
1093 static void gas_switch_set(void) | 1111 static void gas_switch_set(void) |
1094 { | 1112 { |
1095 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= 5 ); | 1113 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= NUM_GAS ); |
1096 | 1114 |
1097 if( sim_gas_last_used == 0 ) | 1115 if( sim_gas_last_used == 0 ) |
1098 { | 1116 { |
1099 calc_N2_ratio = N2_ratio; | 1117 calc_N2_ratio = N2_ratio; |
1100 calc_He_ratio = He_ratio; | 1118 calc_He_ratio = He_ratio; |
1175 | 1193 |
1176 // Kludge: the 0.0002 of 0.7902 are missing with standard air. | 1194 // Kludge: the 0.0002 of 0.7902 are missing with standard air. |
1177 N2_ratio = 0.7902; | 1195 N2_ratio = 0.7902; |
1178 pres_respiration = int_I_pres_respiration * 0.001; | 1196 pres_respiration = int_I_pres_respiration * 0.001; |
1179 | 1197 |
1180 for(ci=0; ci<16; ci++) | 1198 for(ci=0; ci<NUM_COMP; ci++) |
1181 { | 1199 { |
1182 // cycle through the 16 Bühlmann tissues | 1200 // cycle through the 16 Bühlmann tissues |
1183 overlay float p = N2_ratio * (pres_respiration - ppWater); | 1201 overlay float p = N2_ratio * (pres_respiration - ppWater); |
1184 pres_tissue[ci] = p; | 1202 pres_tissue[ci] = p; |
1185 | 1203 |
1186 // cycle through the 16 Bühlmann tissues for Helium | 1204 // cycle through the 16 Bühlmann tissues for Helium |
1187 (pres_tissue+16)[ci] = 0.0; | 1205 (pres_tissue+NUM_COMP)[ci] = 0.0; |
1188 } // for 0 to 16 | 1206 } // for 0 to 15 |
1189 | 1207 |
1190 clear_deco_table(); | 1208 clear_deco_table(); |
1191 char_O_deco_status = 0; | 1209 char_O_deco_status = 0; |
1192 char_O_nullzeit = 0; | 1210 char_O_nullzeit = 0; |
1193 int_O_ascenttime = 0; | 1211 int_O_ascenttime = 0; |
1444 | 1462 |
1445 // Calc limit for surface, ie. GF_high. | 1463 // Calc limit for surface, ie. GF_high. |
1446 calc_limit(); | 1464 calc_limit(); |
1447 | 1465 |
1448 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000); | 1466 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); | 1467 int_O_gtissue_press = (short)((pres_tissue[char_O_gtissue_no] + (pres_tissue+NUM_COMP)[char_O_gtissue_no]) * 1000); |
1450 | 1468 |
1451 // if guiding tissue can not be exposed to surface pressure immediately | 1469 // if guiding tissue can not be exposed to surface pressure immediately |
1452 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) | 1470 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) |
1453 { | 1471 { |
1454 char_O_nullzeit = 0; // deco necessary | 1472 char_O_nullzeit = 0; // deco necessary |
1614 static void calc_tissue(PARAMETER unsigned char period) | 1632 static void calc_tissue(PARAMETER unsigned char period) |
1615 { | 1633 { |
1616 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m | 1634 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m |
1617 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m | 1635 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m |
1618 | 1636 |
1619 for (ci=0;ci<16;ci++) | 1637 for (ci=0;ci<NUM_COMP;ci++) |
1620 { | 1638 { |
1621 read_buhlmann_times(period); // 2 sec or 1 min period. | 1639 read_buhlmann_times(period); // 2 sec or 1 min period. |
1622 | 1640 |
1623 // N2 | 1641 // N2 |
1624 temp_tissue = (ppN2 - pres_tissue[ci]) * var_N2_e; | 1642 temp_tissue = (ppN2 - pres_tissue[ci]) * var_N2_e; |
1625 temp_tissue_safety(); | 1643 temp_tissue_safety(); |
1626 pres_tissue[ci] += temp_tissue; | 1644 pres_tissue[ci] += temp_tissue; |
1627 | 1645 |
1628 // He | 1646 // He |
1629 temp_tissue = (ppHe - (pres_tissue+16)[ci]) * var_He_e; | 1647 temp_tissue = (ppHe - (pres_tissue+NUM_COMP)[ci]) * var_He_e; |
1630 temp_tissue_safety(); | 1648 temp_tissue_safety(); |
1631 (pres_tissue+16)[ci] += temp_tissue; | 1649 (pres_tissue+NUM_COMP)[ci] += temp_tissue; |
1632 } | 1650 } |
1633 } | 1651 } |
1634 | 1652 |
1635 ////////////////////////////////////////////////////////////////////////////// | 1653 ////////////////////////////////////////////////////////////////////////////// |
1636 // calc_limit | 1654 // calc_limit |
1640 static void calc_limit(void) | 1658 static void calc_limit(void) |
1641 { | 1659 { |
1642 char_O_gtissue_no = 255; | 1660 char_O_gtissue_no = 255; |
1643 calc_lead_tissue_limit = 0.0; | 1661 calc_lead_tissue_limit = 0.0; |
1644 | 1662 |
1645 for(ci=0; ci<16;ci++) | 1663 for(ci=0; ci<NUM_COMP;ci++) |
1646 { | 1664 { |
1647 overlay float N2 = pres_tissue[ci]; | 1665 overlay float N2 = pres_tissue[ci]; |
1648 overlay float He = (pres_tissue+16)[ci]; | 1666 overlay float He = (pres_tissue+NUM_COMP)[ci]; |
1649 overlay float p = N2 + He; | 1667 overlay float p = N2 + He; |
1650 | 1668 |
1651 read_buhlmann_coefficients(); | 1669 read_buhlmann_coefficients(); |
1652 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; | 1670 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; | 1671 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; |
1673 char_O_gtissue_no = ci; | 1691 char_O_gtissue_no = ci; |
1674 calc_lead_tissue_limit = p; | 1692 calc_lead_tissue_limit = p; |
1675 } | 1693 } |
1676 } | 1694 } |
1677 | 1695 |
1678 assert( char_O_gtissue_no < 16 ); | 1696 assert( char_O_gtissue_no < NUM_COMP ); |
1679 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); | 1697 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); |
1680 } | 1698 } |
1681 | 1699 |
1682 ////////////////////////////////////////////////////////////////////////////// | 1700 ////////////////////////////////////////////////////////////////////////////// |
1683 // calc_nullzeit | 1701 // calc_nullzeit |
1726 // | 1744 // |
1727 void backup_sim_pres_tissue(void) | 1745 void backup_sim_pres_tissue(void) |
1728 { | 1746 { |
1729 overlay unsigned char x; | 1747 overlay unsigned char x; |
1730 | 1748 |
1731 for(x = 0; x<32; x++) | 1749 for(x = 0; x<2*NUM_COMP; x++) |
1732 sim_pres_tissue_backup[x] = sim_pres_tissue[x]; | 1750 sim_pres_tissue_backup[x] = sim_pres_tissue[x]; |
1733 } | 1751 } |
1734 | 1752 |
1735 ////////////////////////////////////////////////////////////////////////////// | 1753 ////////////////////////////////////////////////////////////////////////////// |
1736 // restore_sim_pres_tissue | 1754 // restore_sim_pres_tissue |
1737 // | 1755 // |
1738 void restore_sim_pres_tissue(void) | 1756 void restore_sim_pres_tissue(void) |
1739 { | 1757 { |
1740 overlay unsigned char x; | 1758 overlay unsigned char x; |
1741 | 1759 |
1742 for(x = 0; x<32; x++) | 1760 for(x = 0; x<2*NUM_COMP; x++) |
1743 sim_pres_tissue[x] = sim_pres_tissue_backup[x]; | 1761 sim_pres_tissue[x] = sim_pres_tissue_backup[x]; |
1744 } | 1762 } |
1745 | 1763 |
1746 ////////////////////////////////////////////////////////////////////////////// | 1764 ////////////////////////////////////////////////////////////////////////////// |
1747 // calc_ascenttime | 1765 // calc_ascenttime |
1759 overlay float ascent = pres_respiration - pres_surface + 0.7; | 1777 overlay float ascent = pres_respiration - pres_surface + 0.7; |
1760 if (ascent < 0.0) | 1778 if (ascent < 0.0) |
1761 ascent = 0.0; | 1779 ascent = 0.0; |
1762 sum = (unsigned short)(ascent + 0.99); | 1780 sum = (unsigned short)(ascent + 0.99); |
1763 | 1781 |
1764 for(x=0; x<32 && internal_deco_depth[x]; x++) | 1782 for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++) |
1765 sum += (unsigned short)internal_deco_time[x]; | 1783 sum += (unsigned short)internal_deco_time[x]; |
1766 | 1784 |
1767 if( char_O_deco_status == 1 ) | 1785 if( char_O_deco_status == 1 ) |
1768 int_O_ascenttime = sum; | 1786 int_O_ascenttime = sum; |
1769 else | 1787 else |
1778 void update_startvalues(void) | 1796 void update_startvalues(void) |
1779 { | 1797 { |
1780 overlay unsigned char x; | 1798 overlay unsigned char x; |
1781 | 1799 |
1782 // Start ascent simulation with current tissue partial pressures. | 1800 // Start ascent simulation with current tissue partial pressures. |
1783 for (x = 0;x<16;x++) | 1801 for (x = 0;x<NUM_COMP;x++) |
1784 { | 1802 { |
1785 sim_pres_tissue[x] = pres_tissue[x]; | 1803 sim_pres_tissue[x] = pres_tissue[x]; |
1786 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; | 1804 (sim_pres_tissue+NUM_COMP)[x] = (pres_tissue+NUM_COMP)[x]; |
1787 } | 1805 } |
1788 | 1806 |
1789 // No leading tissue (yet) for this ascent simulation. | 1807 // No leading tissue (yet) for this ascent simulation. |
1790 sim_lead_tissue_limit = 0.0; | 1808 sim_lead_tissue_limit = 0.0; |
1791 sim_lead_tissue_no = 255; | 1809 sim_lead_tissue_no = 255; |
1802 static void sim_tissue(PARAMETER unsigned char period) | 1820 static void sim_tissue(PARAMETER unsigned char period) |
1803 { | 1821 { |
1804 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m | 1822 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m |
1805 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m | 1823 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m |
1806 | 1824 |
1807 for(ci=0; ci<16; ci++) | 1825 for(ci=0; ci<NUM_COMP; ci++) |
1808 { | 1826 { |
1809 read_buhlmann_times(period); // 1 or 10 minute(s) interval | 1827 read_buhlmann_times(period); // 1 or 10 minute(s) interval |
1810 | 1828 |
1811 // N2 | 1829 // N2 |
1812 temp_tissue = (ppN2 - sim_pres_tissue[ci]) * var_N2_e; | 1830 temp_tissue = (ppN2 - sim_pres_tissue[ci]) * var_N2_e; |
1813 temp_tissue_safety(); | 1831 temp_tissue_safety(); |
1814 sim_pres_tissue[ci] += temp_tissue; | 1832 sim_pres_tissue[ci] += temp_tissue; |
1815 | 1833 |
1816 // He | 1834 // He |
1817 temp_tissue = (ppHe - (sim_pres_tissue+16)[ci]) * var_He_e; | 1835 temp_tissue = (ppHe - (sim_pres_tissue+NUM_COMP)[ci]) * var_He_e; |
1818 temp_tissue_safety(); | 1836 temp_tissue_safety(); |
1819 (sim_pres_tissue+16)[ci] += temp_tissue; | 1837 (sim_pres_tissue+NUM_COMP)[ci] += temp_tissue; |
1820 } | 1838 } |
1821 } | 1839 } |
1822 | 1840 |
1823 ////////////////////////////////////////////////////////////////////////////// | 1841 ////////////////////////////////////////////////////////////////////////////// |
1824 // sim_limit() | 1842 // sim_limit() |
1833 assert( 0.0 < GF_current && GF_current <= 1.0f); | 1851 assert( 0.0 < GF_current && GF_current <= 1.0f); |
1834 | 1852 |
1835 sim_lead_tissue_limit = 0.0; | 1853 sim_lead_tissue_limit = 0.0; |
1836 sim_lead_tissue_no = 0; // If no one is critic, keep first tissue. | 1854 sim_lead_tissue_no = 0; // If no one is critic, keep first tissue. |
1837 | 1855 |
1838 for(ci=0; ci<16; ci++) | 1856 for(ci=0; ci<NUM_COMP; ci++) |
1839 { | 1857 { |
1840 overlay float N2 = sim_pres_tissue[ci]; | 1858 overlay float N2 = sim_pres_tissue[ci]; |
1841 overlay float He = (sim_pres_tissue+16)[ci]; | 1859 overlay float He = (sim_pres_tissue+NUM_COMP)[ci]; |
1842 overlay float p = N2 + He; | 1860 overlay float p = N2 + He; |
1843 | 1861 |
1844 read_buhlmann_coefficients(); | 1862 read_buhlmann_coefficients(); |
1845 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; | 1863 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; | 1864 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; |
1862 sim_lead_tissue_no = ci; | 1880 sim_lead_tissue_no = ci; |
1863 sim_lead_tissue_limit = p; | 1881 sim_lead_tissue_limit = p; |
1864 } | 1882 } |
1865 } // for ci | 1883 } // for ci |
1866 | 1884 |
1867 assert( sim_lead_tissue_no < 16 ); | 1885 assert( sim_lead_tissue_no < NUM_COMP ); |
1868 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 ); | 1886 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 ); |
1869 } | 1887 } |
1870 | 1888 |
1871 ////////////////////////////////////////////////////////////////////////////// | 1889 ////////////////////////////////////////////////////////////////////////////// |
1872 // clear_deco_table | 1890 // clear_deco_table |
1875 // | 1893 // |
1876 static void clear_deco_table(void) | 1894 static void clear_deco_table(void) |
1877 { | 1895 { |
1878 overlay unsigned char x; | 1896 overlay unsigned char x; |
1879 | 1897 |
1880 for(x=0; x<32; ++x) | 1898 for(x=0; x<NUM_STOPS; ++x) |
1881 { | 1899 { |
1882 internal_deco_time [x] = 0; | 1900 internal_deco_time [x] = 0; |
1883 internal_deco_depth[x] = 0; | 1901 internal_deco_depth[x] = 0; |
1884 } | 1902 } |
1885 } | 1903 } |
1899 { | 1917 { |
1900 overlay unsigned char x; | 1918 overlay unsigned char x; |
1901 assert( temp_depth_limit < 128 ); // Can't be negativ (overflown). | 1919 assert( temp_depth_limit < 128 ); // Can't be negativ (overflown). |
1902 assert( temp_depth_limit > 0 ); // No stop at surface... | 1920 assert( temp_depth_limit > 0 ); // No stop at surface... |
1903 | 1921 |
1904 for(x=0; x<32; ++x) | 1922 for(x=0; x<NUM_STOPS; ++x) |
1905 { | 1923 { |
1906 // Make sure deco-stops are recorded in order: | 1924 // Make sure deco-stops are recorded in order: |
1907 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) ); | 1925 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) ); |
1908 | 1926 |
1909 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit ) | 1927 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit ) |
1941 // | 1959 // |
1942 static void calc_gradient_factor(void) | 1960 static void calc_gradient_factor(void) |
1943 { | 1961 { |
1944 overlay float gf; | 1962 overlay float gf; |
1945 overlay float N2 = pres_tissue[char_O_gtissue_no]; | 1963 overlay float N2 = pres_tissue[char_O_gtissue_no]; |
1946 overlay float He = (pres_tissue+16)[char_O_gtissue_no]; | 1964 overlay float He = (pres_tissue+NUM_COMP)[char_O_gtissue_no]; |
1947 | 1965 |
1948 assert( char_O_gtissue_no < 16 ); | 1966 assert( char_O_gtissue_no < NUM_COMP ); |
1949 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); | 1967 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); |
1950 | 1968 |
1951 // tissue > respiration (currently off-gasing) | 1969 // tissue > respiration (currently off-gasing) |
1952 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium. | 1970 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium. |
1953 // GF = 100% when respiration == limit. | 1971 // GF = 100% when respiration == limit. |
2016 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier | 2034 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier |
2017 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31] | 2035 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31] |
2018 // | 2036 // |
2019 void deco_calc_desaturation_time(void) | 2037 void deco_calc_desaturation_time(void) |
2020 { | 2038 { |
2039 overlay rom const float *ptr; | |
2040 | |
2021 RESET_C_STACK | 2041 RESET_C_STACK |
2022 | 2042 |
2023 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); | 2043 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); |
2024 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); | 2044 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); |
2025 | 2045 |
2038 pres_surface = int_I_pres_surface * 0.001; | 2058 pres_surface = int_I_pres_surface * 0.001; |
2039 ppN2 = N2_ratio * (pres_surface - ppWater); | 2059 ppN2 = N2_ratio * (pres_surface - ppWater); |
2040 int_O_desaturation_time = 0; | 2060 int_O_desaturation_time = 0; |
2041 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 2061 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) |
2042 | 2062 |
2043 for (ci=0;ci<16;ci++) | 2063 ptr = &buhlmann_ht[0]; |
2044 { | 2064 for (ci=0;ci<NUM_COMP;ci++) |
2065 { | |
2066 overlay float var_N2_halftime = *ptr++; | |
2067 overlay float var_He_halftime = *ptr++; | |
2045 overlay unsigned short desat_time; // For a particular compartiment, in min. | 2068 overlay unsigned short desat_time; // For a particular compartiment, in min. |
2046 overlay float temp1; | 2069 overlay float temp1; |
2047 overlay float temp2; | 2070 overlay float temp2; |
2048 overlay float temp3; | 2071 overlay float temp3; |
2049 overlay float temp4; | 2072 overlay float temp4; |
2050 | 2073 |
2074 assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 ); | |
2075 assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 ); | |
2076 | |
2051 // saturation_time (for flight) and N2_saturation in multiples of halftime | 2077 // 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 ) | 2078 // 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 ) | 2079 // 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 | 2080 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations |
2055 // N2 | 2081 // N2 |
2062 } | 2088 } |
2063 else | 2089 else |
2064 temp1 = temp1 / temp2; | 2090 temp1 = temp1 / temp2; |
2065 if( 0.0 < temp1 && temp1 < 1.0 ) | 2091 if( 0.0 < temp1 && temp1 < 1.0 ) |
2066 { | 2092 { |
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. | 2093 // 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. | 2094 // minus because log is negative. |
2072 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary. | 2095 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 | 2096 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 | 2097 |
2078 temp1 = 0.0; | 2101 temp1 = 0.0; |
2079 temp2 = 0.0; | 2102 temp2 = 0.0; |
2080 } | 2103 } |
2081 | 2104 |
2082 // He | 2105 // He |
2083 temp3 = 0.1 - (pres_tissue+16)[ci]; | 2106 temp3 = 0.1 - (pres_tissue+NUM_COMP)[ci]; |
2084 if (temp3 >= 0.0) | 2107 if (temp3 >= 0.0) |
2085 { | 2108 { |
2086 temp3 = 0.0; | 2109 temp3 = 0.0; |
2087 temp4 = 0.0; | 2110 temp4 = 0.0; |
2088 } | 2111 } |
2089 else | 2112 else |
2090 temp3 = - temp3 / (pres_tissue+16)[ci]; | 2113 temp3 = - temp3 / (pres_tissue+NUM_COMP)[ci]; |
2091 if( 0.0 < temp3 && temp3 < 1.0 ) | 2114 if( 0.0 < temp3 && temp3 < 1.0 ) |
2092 { | 2115 { |
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. | 2116 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. | 2117 // 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 | 2118 // 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 | 2119 temp4 = var_He_halftime * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier |
2100 } | 2120 } |
2127 temp4 = temp4 + 80.0; // set center | 2147 temp4 = temp4 + 80.0; // set center |
2128 if (temp4 < 0.0) | 2148 if (temp4 < 0.0) |
2129 temp4 = 0.0; | 2149 temp4 = 0.0; |
2130 if (temp4 > 255.0) | 2150 if (temp4 > 255.0) |
2131 temp4 = 255.0; | 2151 temp4 = 255.0; |
2132 (char_O_tissue_saturation+16)[ci] = (char)temp4; | 2152 (char_O_tissue_saturation+NUM_COMP)[ci] = (char)temp4; |
2133 } // for | 2153 } // for |
2134 } | 2154 } |
2135 | 2155 |
2136 ////////////////////////////////////////////////////////////////////////////// | 2156 ////////////////////////////////////////////////////////////////////////////// |
2137 // calc_wo_deco_step_1_min | 2157 // calc_wo_deco_step_1_min |
2159 ppN2 = N2_ratio * (pres_respiration - ppWater); // ppWater is the extra pressure in the body | 2179 ppN2 = N2_ratio * (pres_respiration - ppWater); // ppWater is the extra pressure in the body |
2160 ppHe = 0.0; | 2180 ppHe = 0.0; |
2161 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 2181 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; | 2182 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; |
2163 | 2183 |
2164 calc_tissue(1); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 2184 calc_tissue(1); // update the pressure in the 2*NUM_COMP tissues in accordance with the new ambient pressure |
2165 | 2185 |
2166 clear_deco_table(); | 2186 clear_deco_table(); |
2167 char_O_deco_status = 3; // surface new in v.102 : stays in surface state. | 2187 char_O_deco_status = 3; // surface new in v.102 : stays in surface state. |
2168 char_O_nullzeit = 0; | 2188 char_O_nullzeit = 0; |
2169 int_O_ascenttime = 0; | 2189 int_O_ascenttime = 0; |
2404 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0) or bar/min. | 2424 // 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 | 2425 // Output: int_O_gas_volumes[0..4] in litters * 0.1 |
2406 // | 2426 // |
2407 void deco_gas_volumes(void) | 2427 void deco_gas_volumes(void) |
2408 { | 2428 { |
2409 overlay float volumes[5]; | 2429 overlay float volumes[NUM_GAS]; |
2410 overlay float bottom_usage, ascent_usage; | 2430 overlay float bottom_usage, ascent_usage; |
2411 overlay unsigned char i, deepest_first; | 2431 overlay unsigned char i, deepest_first; |
2412 overlay unsigned char gas; | 2432 overlay unsigned char gas; |
2413 RESET_C_STACK | 2433 RESET_C_STACK |
2414 | 2434 |
2415 //---- initialize with bottom consumption -------------------------------- | 2435 //---- initialize with bottom consumption -------------------------------- |
2416 for(i=0; i<5; ++i) // Nothing yet... | 2436 for(i=0; i<NUM_GAS; ++i) // Nothing yet... |
2417 volumes[i] = 0.0; | 2437 volumes[i] = 0.0; |
2418 | 2438 |
2419 assert(1 <= char_I_first_gas && char_I_first_gas <= 5); | 2439 assert(1 <= char_I_first_gas && char_I_first_gas <= NUM_GAS); |
2420 gas = char_I_first_gas - 1; | 2440 gas = char_I_first_gas - 1; |
2421 | 2441 |
2422 bottom_usage = read_custom_function(56) * 0.1; | 2442 bottom_usage = read_custom_function(56) * 0.1; |
2423 if( bottom_usage > 0.0 ) | 2443 if( bottom_usage > 0.0 ) |
2424 volumes[gas] | 2444 volumes[gas] |
2444 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min) | 2464 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min) |
2445 * ascent_usage; // Consumption ( xxx / min @ 1 bar) | 2465 * ascent_usage; // Consumption ( xxx / min @ 1 bar) |
2446 else | 2466 else |
2447 volumes[gas] = 65535.0; | 2467 volumes[gas] = 65535.0; |
2448 | 2468 |
2449 for(i=0; i<32; ++i) | 2469 for(i=0; i<NUM_STOPS; ++i) |
2450 { | 2470 { |
2451 overlay unsigned char j; | 2471 overlay unsigned char j; |
2452 overlay unsigned char depth, time, ascent; | 2472 overlay unsigned char depth, time, ascent; |
2453 | 2473 |
2454 // Manage stops in reverse order (CF#54) | 2474 // Manage stops in reverse order (CF#54) |
2470 if( i < 31 ) | 2490 if( i < 31 ) |
2471 ascent -= char_O_deco_depth[30-i] & 0x7F; | 2491 ascent -= char_O_deco_depth[30-i] & 0x7F; |
2472 } | 2492 } |
2473 | 2493 |
2474 // Gas switch depth ? | 2494 // Gas switch depth ? |
2475 for(j=0; j<5; ++j) | 2495 for(j=0; j<NUM_GAS; ++j) |
2476 { | 2496 { |
2477 if( depth <= char_I_deco_gas_change[j] ) | 2497 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]) ) | 2498 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) ) |
2479 gas = j; | 2499 gas = j; |
2480 } | 2500 } |
2492 else | 2512 else |
2493 volumes[gas] = 65535.0; | 2513 volumes[gas] = 65535.0; |
2494 } | 2514 } |
2495 | 2515 |
2496 //---- convert results for the ASM interface ----------------------------- | 2516 //---- convert results for the ASM interface ----------------------------- |
2497 for(i=0; i<5; ++i) | 2517 for(i=0; i<NUM_GAS; ++i) |
2498 if( volumes[i] > 6553.4 ) | 2518 if( volumes[i] > 6553.4 ) |
2499 int_O_gas_volumes[i] = 65535; | 2519 int_O_gas_volumes[i] = 65535; |
2500 else | 2520 else |
2501 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5); | 2521 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5); |
2502 } | 2522 } |
2507 { | 2527 { |
2508 overlay unsigned char x; | 2528 overlay unsigned char x; |
2509 RESET_C_STACK | 2529 RESET_C_STACK |
2510 | 2530 |
2511 cns_vault = CNS_fraction; | 2531 cns_vault = CNS_fraction; |
2512 for (x=0;x<32;x++) | 2532 for (x=0;x<2*NUM_COMP;x++) |
2513 pres_tissue_vault[x] = pres_tissue[x]; | 2533 pres_tissue_vault[x] = pres_tissue[x]; |
2514 } | 2534 } |
2515 | 2535 |
2516 void deco_pull_tissues_from_vault(void) | 2536 void deco_pull_tissues_from_vault(void) |
2517 { | 2537 { |
2518 overlay unsigned char x; | 2538 overlay unsigned char x; |
2519 RESET_C_STACK | 2539 RESET_C_STACK |
2520 | 2540 |
2521 for (x=0;x<32;x++) | 2541 for (x=0;x<2*NUM_COMP;x++) |
2522 pres_tissue[x] = pres_tissue_vault[x]; | 2542 pres_tissue[x] = pres_tissue_vault[x]; |
2523 | 2543 |
2524 // Restore both CNS variable, too. | 2544 // Restore both CNS variable, too. |
2525 CNS_fraction = cns_vault; | 2545 CNS_fraction = cns_vault; |
2526 char_O_CNS_fraction = (char)(CNS_fraction * 100.0 + 0.5); | 2546 char_O_CNS_fraction = (char)(CNS_fraction * 100.0 + 0.5); |