Mercurial > public > hwos_code
diff src/divemode.asm @ 604:ca4556fb60b9
bump to 2.99beta, work on 3.00 stable
author | heinrichsweikamp |
---|---|
date | Thu, 22 Nov 2018 19:47:26 +0100 |
parents | 08a0162d3ca1 |
children | 5ce603c29750 |
line wrap: on
line diff
--- a/src/divemode.asm Thu Oct 11 21:06:29 2018 +0200 +++ b/src/divemode.asm Thu Nov 22 19:47:26 2018 +0100 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File divemode.asm REFACTORED VERSION V2.98 +; File divemode.asm REFACTORED VERSION V2.99e ; ; Divemode ; @@ -9,8 +9,8 @@ ; HISTORY ; 2011-08-15 : [mH] moving from OSTC code -#include "hwos.inc" ; Mandatory header -#include "shared_definitions.h" ; Mailbox from/to p2_deco.c +#include "hwos.inc" ; mandatory header +#include "shared_definitions.h" ; mailbox from/to p2_deco.c #include "tft_outputs.inc" #include "strings.inc" #include "tft.inc" @@ -26,6 +26,10 @@ #include "calibrate.inc" #include "convert.inc" + IFDEF _rx_functions +#include "rx_ops.inc" + ENDIF + extern TFT_dive_compass_heading extern do_line_menu @@ -38,37 +42,50 @@ CBLOCK local1 ; max size is 16 Byte !!! apnoe_timeout_counter ; timeout counter for apnoe mode - average_depth_hold:4 ; used in calculation of the average depth sensor_setpoint ; sensor ppo2 in 0.01bar for deco routine - active_diluent ; backup of diluent gas for when switching back from bailout to CCR/pSCR loop - average_depth_hold_total:4 ; used to calculate the average depth - ENDC ; used: 11 byte, remaining: 5 byte - -gui CODE + check_gas_num ; used in search for best gas/dil: current gas/dil number (1-5) + check_gas_depth ; used in search for best gas/dil: current gas/dil change depth + check_gas_type ; used in search for best gas/dil: current gas/dil type + check_gas_O2_ratio ; used in search for best gas/dil: current gas/dil O2 ratio + best_gas_num ; used in search for best gas/dil: best gas/dil number (1-5) CAUTION: there is also a variable named best_gas_number ! + best_gas_depth ; used in search for best gas/dil: best gas/dil change depth + ppO2_min ; used in search for best gas/dil: minimum ppO2 required + ppO2_max ; used in search for best gas/dil: maximum ppO2 allowed + ENDC ; used: 10 byte, remaining: 6 byte + + CBLOCK local2 ; max size is 16 Byte !!! + average_depth_hold:4 ; used to calculate the resettable average depth + average_depth_hold_total:4 ; used to calculate the absolute average depth + ENDC ; used: 8 byte, remaining: 8 byte + +dmode CODE ;============================================================================= global diveloop diveloop: - banksel common + banksel common call speed_normal - call diveloop_boot ; Boot tasks for all modes - - ; Startup Tasks for all modes - call TFT_boot ; Initialize TFT (includes clear screen) - bsf FLAG_TFT_divemode_mask ; Display mask - movff customview_divemode,menupos3; Reload last customview - call customview_mask ; Redraw last custom view + call diveloop_boot ; boot tasks for all modes + + ; startup tasks for all modes + call TFT_boot ; initialize TFT (includes clear screen) + bsf FLAG_TFT_divemode_mask ; request display of dive mode mask + + movff customview_divemode,menupos3; reload last custom view + bsf redraw_custview_mask ; request redraw of last custom view btfsc FLAG_apnoe_mode - bsf realdive ; Set Realdive flag in Apnoe mode - - btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode + bsf realdive ; set realdive flag in apnoe mode + + btfsc FLAG_apnoe_mode ; done for apnoe or gauge mode bra diveloop_loop_start - btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode + btfsc FLAG_gauge_mode ; done for apnoe or gauge mode bra diveloop_loop_start - bsf FLAG_TFT_display_ndl_mask ; display "NDL" + ; Deco modes + bsf FLAG_TFT_active_gas_divemode; request display of gas and setpoint + bsf FLAG_TFT_display_ndl_mask ; request display of "NDL" ; +@5 init clrf WREG ; WAIT marker: display "---" @@ -79,37 +96,53 @@ movff WREG,int_O_alternate_ascenttime+1 diveloop_loop_start: + btfsc FLAG_TFT_divemode_mask + call TFT_divemode_mask btfsc FLAG_TFT_display_ndl_mask call TFT_display_ndl_mask - -diveloop_loop: ; The diveloop starts here +diveloop_loop: ; the dive loop starts here btfss quarter_second_update bra diveloop_loop1 ; tasks any 1/4 second, any mode bcf quarter_second_update ; clear flag - movlw .6 - cpfseq menupos3 ; in compass view? - bra diveloop_loop1 ; No, done. - - btfsc alternative_divelayout ; In alternative layout mode? - bra diveloop_loop1 ; Yes, done. No Compass. - -; TFT Output routines - call TFT_dive_compass_heading ; Yes, update compass heading value - bsf FLAG_TFT_temp_divemode ; Redraw temperature (is slightly affected from compass heading arrow) -; TFT Output routines + btfsc alternative_divelayout ; in alternative layout? + bra diveloop_loop1 ; YES - no compass in alternative layout mode + movlw index_compass_dm ; NO - index of compass view + cpfseq menupos3 ; - in compass view? + bra diveloop_loop1 ; NO - done + call TFT_dive_compass_heading ; YES - update compass heading value + bsf FLAG_TFT_temp_divemode ; - redraw temperature (is slightly affected from compass heading arrow) diveloop_loop1: - btfss onesecupdate - bra diveloop_loop3 + btfss onesecupdate ; next second begun? + bra diveloop_loop3 ; NO ; tasks any new second... bcf onesecupdate ; one seconds update, clear flag here in case it's set again in ISR before all tasks are done. - ;bsf LEDg ; ### USE FOR DEBUG ONLY - RESETS RX CIRCUITRY ### +; ###-- USE FOR DEBUG ONLY - RESETS RX CIRCUITRY --### +; bsf LEDg +; ###----------------------------------------------### + + ; compute current depth in meters + SAFE_2BYTE_COPY rel_pressure,xA + movlw .100 + movwf xB+0 + clrf xB+1 + call div16x16 ; xC = xA / xB, xC+0 now holds depth in full meters + movff xC+0,curr_depth ; store result in curr_depth + + ; compute ambient pressure / 10, will be needed later + SAFE_2BYTE_COPY amb_pressure,xA + movlw .10 + movwf xB+0 + clrf xB+1 + call div16x16 ; xC = xA / xB = p_amb / 10 + movff xC+0,amb_press_10+0 ; store result for later use + movff xC+1,amb_press_10+1 ; ... ; display depth based on full seconds interval (nicer blinking) btfss alternative_divelayout @@ -117,22 +150,29 @@ btfsc alternative_divelayout rcall TFT_output4_alternative - btfsc FLAG_apnoe_mode ; Only in apnoe mode - bra diveloop_loop1_nonedeco ; One Second Tasks in Apnoe mode + btfsc FLAG_apnoe_mode ; in Apnoe mode? + bra diveloop_loop1_nonedeco ; YES - do Apnoe mode every second tasks ; tasks any new second - only for deco modes -diveloop_loop1_decomodes: - bsf FLAG_TFT_divemins ; Display (new) divetime! - btfsc show_safety_stop ; Show the safety stop? - bsf FLAG_TFT_show_safety_stop ; Yes, show/delete if done. +diveloop_loop1_deco: + bsf FLAG_TFT_divemins ; display (new) dive time! + btfsc show_safety_stop ; show the safety stop? + bsf FLAG_TFT_show_safety_stop ; YES - show/delete if done btfss alternative_divelayout rcall TFT_output1_normal btfsc alternative_divelayout rcall TFT_output1_alternative - btfsc FLAG_ccr_mode ; in CCR mode... - call check_dive_autosp ; ...check for Auto-SP + call divemode_check_for_warnings ; check for warnings + + IFDEF _rx_functions + btfss FLAG_tr_enabled ; TR functions enabled? + bra diveloop_loop1_deco1 ; NO - skip pressure readings part + call get_pressure_readings ; YES - get pressure readings + call configure_sac_calculation ; - set up SAC calculation +diveloop_loop1_deco1: + ENDIF call calc_deko_divemode ; calculate decompression and set resulting display flags @@ -140,124 +180,108 @@ rcall TFT_output2_normal btfsc alternative_divelayout rcall TFT_output2_alternative - - call divemode_check_for_warnings ; Check for any warnings - - bra diveloop_loop2 ; Common Tasks - + bra diveloop_loop2 ; continue with common tasks ; tasks any new second - only for apnoe mode diveloop_loop1_nonedeco: - rcall divemode_apnoe_tasks ; 1 sec. Apnoe tasks - call customview_second ; Do every-second tasks for the custom view area - ;bra diveloop_loop2 ; Common Tasks + rcall divemode_apnoe_tasks ; 1 sec. apnoe tasks + call customview_second ; do every-second tasks for the custom view area + ;bra diveloop_loop2 ; common tasks ; continue tasks any new second, any mode diveloop_loop2: - rcall timeout_divemode ; ** menu timeout? ** This routine sets the required flags + btfsc redraw_custview_mask ; shall we redraw the custom view mask? + call customview_mask ; YES - redraw custom view mask + + rcall timeout_divemode ; ** menu timeout? ** - this routine sets the required flags rcall set_dive_modes ; tests if depth > threshold - rcall set_min_temp ; store min. temp if required (Future hardware will need this to be checked 1/second...) + rcall set_min_temp ; store min. temp if required (future hardware will need this to be checked 1/second...) btfsc oneminupdate ; one minute tasks - rcall update_divemode60 ; Update clock, etc. + rcall update_divemode60 ; update clock, etc. + + btfss FLAG_oc_mode ; are we in OC mode? + bsf FLAG_TFT_active_gas_divemode; NO - have the gas and setpoint redrawn on every second to update setpoint display, animate the blinking, etc. btfss alternative_divelayout rcall TFT_output3_normal btfsc alternative_divelayout rcall TFT_output3_alternative - ;bcf LEDg ; ### USE FOR DEBUG ONLY - RESETS RX CIRCUITRY ### +; ###-- USE FOR DEBUG ONLY - RESETS RX CIRCUITRY --### +; bcf LEDg +; ###----------------------------------------------### ; tasks any round, any mode diveloop_loop3: - call test_switches_divemode ; Check switches in divemode + call test_switches_divemode ; check switches in dive mode global diveloop_loop4 -diveloop_loop4: ; Menu-Exit returns here... - btfsc divemode_menu ; in the big divemode menu? - bra diveloop_loop4b ; YES - no space for CCR/pSCR info - btfsc menuview ; NO - in the small yellow menu? - bra diveloop_loop4b ; YES - no space for CCR/pSCR info - btfsc alternative_divelayout ; NO - in the alternative layout? - bra diveloop_loop4b ; YES - no space for CCR/pSCR info - call TFT_show_mode_divemode ; NO - (re)write CCR/pSCR mode info to display -diveloop_loop4b: - btfsc toggle_customview ; Next view? - call customview_toggle ; Yes, show next customview (and delete this flag) - - btfsc divemode_gaschange ; Gas switch flag set? +diveloop_loop4: ; menu-exit returns here... + btfsc toggle_customview ; next view? + call customview_toggle ; YES - show next custom view (and delete this flag) + + btfsc divemode_gaschange ; gas switch flag set? call gas_switched_common ; YES - btfsc toggle_gf ; Toggle GF/aGF? + btfsc toggle_gf ; toggle GF/aGF? rcall divemodemode_togglegf ; YES - btfsc FLAG_set_marker ; shall a marker be set? + IFDEF _cave_mode + btfsc toggle_turn_dive ; toggle dive turned? + rcall divemodemode_toggleturn ; YES + ENDIF + + btfsc FLAG_set_marker ; shall set a marker? call set_logbook_marker ; YES - btfsc store_sample ; store new sample? - call store_dive_data ; Store profile data - - btfss divemode ; Dive finished? - goto ghostwriter_end_dive ; Dive finished! + btfsc store_sample ; shall store new sample? + call store_dive_data ; YES - store profile data + + btfss divemode ; dive finished? + goto ghostwriter_end_dive ; YES - dive finished! btfsc pressure_refresh ; new pressure available? - rcall set_max_depth ; update max. depth if required + rcall set_max_depth ; YES - update max. depth if required btfsc pressure_refresh ; new pressure available? - bsf FLAG_TFT_depth ; Yes, update depth + bsf FLAG_TFT_depth ; YES - update depth bcf pressure_refresh ; clear flag - btfsc temp_changed - bsf FLAG_TFT_temp_divemode ; Displays temperature - - ; display depth based on as-fast-as-possible (no nice blinking) - ;btfss alternative_divelayout - ;rcall TFT_output4_normal - ;btfsc alternative_divelayout - ;rcall TFT_output4_alternative - - btfsc enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (Screen dump) - bra diveloop_loop5 - bra diveloop_loop6 - -diveloop_loop5: - btfss vusb_in ; USB (still) plugged in? - bcf enable_screen_dumps ; No, clear flag - call rs232_get_byte - btfsc rs232_receive_overflow - bra diveloop_loop6 - movlw "l" - cpfseq RCREG1 - bra diveloop_loop6 - call TFT_dump_screen ; Dump the screen contents - -diveloop_loop6: - bra diveloop_loop ; Loop the divemode + btfsc temp_changed ; temperature changed? + bsf FLAG_TFT_temp_divemode ; YES - display temperature + + IFDEF _screendump + btfsc enable_screen_dumps ; screen dump function enabled? + call TFT_dump_screen_check ; YES - check if requested and do it + ENDIF + + bra diveloop_loop ; loop the dive mode ;-------------------------------------------------------------------------------------------------------- -TFT_output1_normal: ; beginning of any new second - only for deco modes +TFT_output1_normal: ; beginning of any new second - only for deco modes btfsc FLAG_TFT_divemode_mask call TFT_divemode_mask btfsc FLAG_TFT_divemins - call TFT_divemins ; Display (new) divetime! - call customview_second ; Do every-second tasks for the custom view area (In sync with the divetime) mH + call TFT_divemins ; display (new) dive time! + call customview_second ; do every-second tasks for the custom view area (in sync with the dive time) mH btfsc FLAG_TFT_show_safety_stop - call TFT_show_safety_stop ; Show safety stop + call TFT_show_safety_stop ; show safety stop btfsc FLAG_TFT_clear_safety_stop - call TFT_clear_safety_stop ; Clear safety stop + call TFT_clear_safety_stop ; clear safety stop return -TFT_output1_alternative: ; beginning of any new second - only for deco modes +TFT_output1_alternative: ; beginning of any new second - only for deco modes + btfsc FLAG_TFT_divemode_mask_alt + call TFT_divemode_mask_alternative ; alternative mask btfsc FLAG_TFT_divemins - call TFT_divemins_alternative ; Display (new) divetime! - btfsc FLAG_TFT_divemode_mask_alt - call TFT_divemode_mask_alternative ; Alt. mask - call customview_alternative_second ; Do every-second tasks for the custom view area (In sync with the divetime) mH + call TFT_divemins_alternative ; display (new) divetime! + call customview_alternative_second ; do every-second tasks for the custom view area (in sync with the dive time) mH btfsc FLAG_TFT_big_deco_alt - call TFT_big_deco_alt ; Big deco and safety stop + call TFT_big_deco_alt ; big deco, also manages alternative safety stop thus moved to first wave of outputs [rl] return -TFT_output2_normal: ; any new second - only for deco modes +TFT_output2_normal: ; any new second - only for deco modes btfsc FLAG_TFT_display_ndl_mask call TFT_display_ndl_mask btfsc FLAG_TFT_display_ndl @@ -270,56 +294,56 @@ call TFT_display_tts return -TFT_output2_alternative: ; any new second - only for deco modes +TFT_output2_alternative: ; any new second - only for deco modes return -TFT_output3_normal: ; tasks any new second, any mode +TFT_output3_normal: ; tasks any new second, any mode, after deco calculations btfsc FLAG_TFT_max_depth - call TFT_max_depth ; use normal max. depth + call TFT_max_depth ; use normal max. depth btfsc FLAG_TFT_divemode_warning call TFT_divemode_warning btfsc FLAG_TFT_divemode_warning_clear call TFT_divemode_warning_clear - btfsc FLAG_TFT_active_gas_divemode - call TFT_active_gas_divemode ; Display gas/Setpoint btfsc FLAG_TFT_dive_warning_text_clear - call TFT_clear_warning_text ; clear complete warnings area + call TFT_clear_warning_text ; clear complete warnings area btfsc FLAG_TFT_dive_warning_text_clr2 - call TFT_clear_warning_text_2nd_row; clear 2nd row of warnings + call TFT_clear_warning_text_2nd_row ; clear 2nd row of warnings return -TFT_output3_alternative: ; tasks any new second, any mode - btfsc FLAG_TFT_max_depth_alt - call TFT_max_depth_alternative ; big max. depth +TFT_output3_alternative: ; tasks any new second + btfsc FLAG_TFT_max_depth + call TFT_max_depth_alternative ; big max. depth btfsc FLAG_TFT_dive_warning_text_clear - call TFT_clear_warning_text ; clear complete warnings area (In alt mode only 2nd. row...) + call TFT_clear_warning_text ; clear complete warnings area (in alt mode only 2nd row...) return -TFT_output4_normal: ; tasks any round, any mode +TFT_output4_normal: ; tasks any round, any mode, before deco calculations (stable timebase) btfsc FLAG_TFT_depth - call TFT_depth ; Displays new depth + call TFT_depth ; display depth + btfsc FLAG_TFT_active_gas_divemode + call TFT_active_gas_divemode ; display gas/setpoint btfsc FLAG_TFT_temp_divemode - call TFT_temp_divemode ; Update temperature + call TFT_temp_divemode ; update temperature return -TFT_output4_alternative: ; tasks any round, any mode +TFT_output4_alternative: ; tasks any round, any mode btfsc FLAG_TFT_depth - call TFT_depth ; Displays new depth + call TFT_depth ; display new depth return ;-------------------------------------------------------------------------------------------------------- -divemode_apnoe_tasks: ; 1 sec. Apnoe tasks - call TFT_display_apnoe_descent ; Yes, Show descent timer +divemode_apnoe_tasks: ; 1 sec. apnoe tasks + call TFT_display_apnoe_descent ; show descent timer call TFT_max_depth ; use normal max. depth - btfsc divemode2 ; Time running? - bra divemode_apnoe_tasks2 ; New descent, reset data if flag is set + btfsc divemode2 ; time running? + bra divemode_apnoe_tasks2 ; YES - new descent, reset data if flag is set rcall apnoe_calc_maxdepth call TFT_display_apnoe_surface - call TFT_display_apnoe_last_max ; Show last max. depth + call TFT_display_apnoe_last_max ; show last max. depth incf apnoe_surface_secs,F movlw d'60' cpfseq apnoe_surface_secs @@ -328,26 +352,26 @@ incf apnoe_surface_mins,F divemode_apnoe_tasks1: - bcf FLAG_active_descent ; Clear flag - btfsc divemode2 ; Time running? - return ; Yes, return - bsf FLAG_active_descent ; Set Flag + bcf FLAG_active_descent ; clear flag + btfsc divemode2 ; time running? + return ; YES - return + bsf FLAG_active_descent ; set flag return divemode_apnoe_tasks2: - btfss FLAG_active_descent ; Are we descending? - return ; No, We are at the surface - rcall apnoe_calc_maxdepth ; Yes! - call TFT_apnoe_clear_surface ; Clear Surface timer - clrf apnoe_timeout_counter ; Delete timeout + btfss FLAG_active_descent ; are we descending? + return ; NO - we are at the surface + rcall apnoe_calc_maxdepth ; YES + call TFT_apnoe_clear_surface ; clear surface timer + clrf apnoe_timeout_counter ; delete timeout clrf apnoe_surface_secs clrf apnoe_surface_mins clrf apnoe_secs - clrf apnoe_mins ; Reset Descent time + clrf apnoe_mins ; reset descent time movlw .0 movff WREG,max_pressure+0 - movff WREG,max_pressure+1 ; Reset Max. Depth - bcf FLAG_active_descent ; Clear flag + movff WREG,max_pressure+1 ; reset max. depth + bcf FLAG_active_descent ; clear flag return global apnoe_calc_maxdepth @@ -357,8 +381,8 @@ movff max_pressure+0,sub_b+0 movff max_pressure+1,sub_b+1 call subU16 ; sub_c = sub_a - sub_b - ; apnoe_max_pressure<max_pressure -> neg_flag=1 - ; max_pressure<=apnoe_max_pressure -> neg_flag=0 + ; apnoe_max_pressure < max_pressure -> neg_flag=1 + ; max_pressure <= apnoe_max_pressure -> neg_flag=0 btfss neg_flag return ;apnoe_max_pressure<max_pressure @@ -369,148 +393,193 @@ ; -------------------------------------------------------------------------------------- calc_deko_divemode: - rcall calc_deko_divemode2 ; all deco relevant code is now invoked every second - btfsc twosecupdate - bra calc_deko_divemode1 - bsf twosecupdate - return - -calc_deko_divemode1: ; the following code is invoked every 2 seconds - bcf twosecupdate - + btfss FLAG_gauge_mode ; in gauge mode? + rcall calc_deko_engine ; NO - do deco calculations + + ; Increment the time accumulators used for calculating the average depths. + ; This done here and not in the ISR to guarantee synchronism between time + ; and depth accumulator incrementing. + infsnz average_divesecs+0,F + incf average_divesecs+1,F + infsnz average_divesecs_total+0,F + incf average_divesecs_total+1,F + + btg onesectoggle ; toggle the one-second toggle bit + btfss onesectoggle ; toggle bit set? + bra calc_deko_divemode2 ; NO + ;bra calc_deko_divemode1 ; YES + +calc_deko_divemode1: ; every-2-seconds tasks, 1st phase +; call TFT_debug_output ; optional debug output + btfsc FLAG_gauge_mode ; in gauge mode? + return ; YES - done + goto check_gas_best ; NO - checks if a better gas should be selected (by user) and return + +calc_deko_divemode2: ; every-2-seconds tasks, 2nd phase call calc_average_depth ; calculate average depth call calc_velocity ; calculate vertical velocity and display if > threshold (every two seconds) - call set_reset_safety_stop ; Set flags for safety stop and/or reset safety stop - call TFT_debug_output - - btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode - return - btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode - return - -; Check for a gas change - goto check_gas_change ; Checks if a better gas should be selected (by user) and return... - - -calc_deko_divemode2: - btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode - return - - btfsc FLAG_ccr_mode ; In CCR mode? - rcall calc_deko_divemode_sensor ; do sensor data acquisition if applicable by OSTC model - - btfsc FLAG_pscr_mode ; In PSCR mode? - rcall calc_deko_divemode_sensor ; do sensor data acquisition if applicable by OSTC model - - SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; transfer ambient pressure to deco engine + goto set_reset_safety_stop ; set/reset flags for safety stop and return + + +calc_deko_engine: + btfsc FLAG_ccr_mode ; in CCR mode? + call check_dive_autosp ; YES - check for Auto-SP + + btfsc FLAG_ccr_mode ; in CCR mode? + rcall calc_deko_divemode_sensor ; YES - do sensor data acquisition if applicable by OSTC model + + btfsc FLAG_pscr_mode ; in pSCR mode? + rcall calc_deko_divemode_sensor ; YES - do sensor data acquisition if applicable by OSTC model ; check deco engine state and switch between normal and alternative plan calculations ; ; Remark: Any reconfigurations done here do only affect the ascent & deco calculation settings, - ; not the settings for the calculations done on the real tissues. The later ones are only - ; altered in case of a gas change, or in case of a real bailout or switchback to setpoint - ; or sensor, respectively. - ; In case of a gas change or real bailout/switchback, the settings for the deco calculations - ; are also changed to match the settings for the real tissues. This is done on signal through - ; 'divemode_gaschange' and will also leave the deco engine status in state as if having done - ; the alternative plan last. - - ; check state of ascent/deco calculations - movff char_O_deco_status,lo ; get a working copy of char_O_deco_status into bank common - movlw DECO_STATUS_MASK ; load bit mask covering the deco status bits - andwf lo,W ; mask out bits showing deco engine computations state - tstfsz WREG ; check if the last compute cycle has finished (bits 1 and 0 cleared) - bra calc_deko_divemode2e ; NO - computations still in progress, needs more computation cycles - btfss lo,DECO_PLAN_FLAG ; YES - computation cycle finished, so check what has been computed - bra calc_deko_divemode2b ; PLAN bit is cleared i.e. normal plan was done, may do alternative next - - ; The PLAN bit is set, i.e. an alternative plan was computed in the last cycle, or the deco engine has - ; been restarted because of a gas change etc. --> Reconfigure to normal plan for next computation cycle. - - ; reset flags for special calculations + ; not the settings for the calculations done on the real tissues. The later ones are only + ; altered in case of a gas change, or in case of a real bailout or switchback to setpoint + ; or sensor, respectively. + ; In case of a gas change or real bailout/switchback, the settings for the deco calculations + ; are also changed to match the settings for the real tissues. This is done on signal through + ; 'divemode_gaschange' and will also leave the deco engine status in state as if having done + ; the alternative plan last. + + ; get working copies of char_O_main_status and char_O_deco_status + movff char_O_main_status,hi ; get char_O_main_status into hi + movff char_O_deco_status,lo ; get char_O_deco_status into lo + + ; check state of deco calculations + btfsc hi,DECO_COMPLETED_NORM ; finished calculations for normal plan? + bra calc_deko_engine_alt ; YES - do an alternative plan next (or a normal one with more features enabled) + btfsc hi,DECO_COMPLETED_ALT ; finished calculations for alternative plan? + bra calc_deko_engine_norm ; YES - do a normal plan next + bra calc_deko_engine_cont ; NO to both - continue calculations / do first invocation in INIT mode + +calc_deko_engine_norm: + ; Last cycle did an alternative plan, or the deco engine has been restarted because of a gas change etc. + ; --> Reconfigure to normal plan for next computation cycle. + bcf lo,DECO_PLAN_FLAG ; clear flag for alternative plan to do a normal plan next + bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation + bcf lo,DECO_VOLUME_FLAG ; clear flag for gas needs calculation + bcf lo,DECO_BAILOUT_FLAG ; clear flag for bailout mode + IFDEF _cave_mode + bcf hi,DECO_CAVE_MODE ; clear flag for cave mode + ENDIF + + btfsc FLAG_ccr_mode ; in CCR mode? + bra calc_deko_engine_norm_loop ; YES - reload diluents and reconfigure CCR mode if not in bailout + btfsc FLAG_pscr_mode ; in pSCR mode? + bra calc_deko_engine_norm_loop ; YES - reload diluents and reconfigure pSCR mode if not in bailout + ;bra calc_deko_engine_norm_OC ; neither in CCR nor pSCR mode, so reload OC gases and reconfigure OC mode + ; (first cycle omits gas needs calculation for faster first deco results) +calc_deko_engine_norm_OC: + movff active_gas,WREG ; get current OC gas + call deco_setup_oc_gases_pre ; set up deco calculations in OC mode with OC gases + bra calc_deko_engine_start ; start deco engine + +calc_deko_engine_norm_loop: ; switch to loop calculation if not in a real bailout situation + btfsc FLAG_bailout_mode ; check if a real bailout situation is present + bra calc_deko_engine_norm_OC ; YES - revert to OC mode + ; NO - switch to loop calculation: + movff active_dil,WREG ; - get current diluent + call deco_setup_cc_diluents_pre ; - set up deco calculations in CCR/pSCR mode with diluents + bra calc_deko_engine_start ; - start deco engine + +calc_deko_engine_alt: + ; A normal plan was computed in the last cycle. For the next calculation cycle the mode may be switched + ; to alternative plan, or stay in normal plan but with certain features enabled... + bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation + bcf lo,DECO_VOLUME_FLAG ; clear flag for gas needs calculation + bcf lo,DECO_BAILOUT_FLAG ; clear flag for bailout mode + IFDEF _cave_mode + bcf hi,DECO_CAVE_MODE ; clear flag for cave mode + ENDIF + + btfsc FLAG_bailout_mode ; check if a real bailout situation is present + bra calc_deko_engine_alt_1 ; YES - stay in normal plan mode and preclude delayed ascent calculation + TSTOSS char_I_extra_time ; NO - check if a delayed ascent is enabled + bra calc_deko_engine_alt_1 ; NO - stay in normal plan mode and preclude delayed ascent calculation + bsf lo,DECO_PLAN_FLAG ; YES - set flag for alternative plan + bsf lo,DECO_ASCENT_FLAG ; - set flag for delayed ascent + +calc_deko_engine_alt_1: + TSTOSS opt_calc_asc_gasvolume ; check if gas volume calculation is enabled + bra calc_deko_engine_start ; NO - no volume calculation, no simulated bailout plan in this case + bsf lo,DECO_VOLUME_FLAG ; YES - set gas needs calculation flag + + btfsc FLAG_bailout_mode ; check if a real bailout situation is present + bra calc_deko_engine_start ; YES - normal plan already does bailout (OC) calculation "for real" + + IFDEF _cave_mode + bsf hi,DECO_CAVE_MODE ; activate cave mode by default + btfss FLAG_cave_mode ; cave mode switched on? + bcf hi,DECO_CAVE_MODE ; NO - deactivate p2deco cave mode again + btfsc FLAG_dive_turned ; dive turned? + bcf hi,DECO_CAVE_MODE ; YES - deactivate p2deco cave mode again + btfsc FLAG_cave_mode_shutdown ; cave mode function shut down? + bcf hi,DECO_CAVE_MODE ; YES - deactivate p2deco cave mode again + ENDIF + + btfss lo,DECO_MODE_LOOP_FLAG ; NO - has a loop mode calculation been done during the normal plan? + bra calc_deko_engine_start ; NO - when not in loop mode, no simulated bailout to be done + decf best_gas_number,W ; YES - get best gas number -1 into WREG. If not available, WREG will be 255 now. If not computed yet, WREG will be 254 now. + btfsc WREG,7 ; - WREG < 128 (a bailout gas is available)? + bra calc_deko_engine_alt_2 ; NO - no simulated bailout possible because no bailout gas available to switch to + bsf lo,DECO_PLAN_FLAG ; YES - set flag for alternative plan + bsf lo,DECO_BAILOUT_FLAG ; - set bailout mode flag (enables gas changes before 1st stop) + movf best_gas_number,W ; - put number of best gas into WREG + call deco_setup_oc_gases_pre ; - set up deco calculations in OC mode with OC gases + bra calc_deko_engine_start ; - start in alternative plan mode + +calc_deko_engine_alt_2: bcf lo,DECO_PLAN_FLAG ; clear flag for alternative plan bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation bcf lo,DECO_VOLUME_FLAG ; clear flag for gas needs calculation + IFDEF _cave_mode + bcf hi,DECO_CAVE_MODE ; clear flag for cave mode + ENDIF + call inval_alternative_plan_data ; invalidate all alternative (bailout) plan data because they are not applicable any more + +calc_deko_engine_start: + IFDEF _cave_mode + movff hi,char_O_main_status ; write-back char_O_main_status to deco engine interface + ENDIF movff lo,char_O_deco_status ; write-back char_O_deco_status to deco engine interface - ; check if a switchback from CCR or pSCR bailout calculation is to be done - btfsc FLAG_ccr_mode ; may a switchback from a CCR bailout calculation be needed? - bra calc_deko_divemode2a ; in CCR mode, so may need to switch back from bailout calculation - btfsc FLAG_pscr_mode ; may a switchback from a pSCR bailout calculation be needed? - bra calc_deko_divemode2a ; in pSCR mode, so may need to switch back from bailout calculation - bra calc_deko_divemode2e ; not in CCR nor pSCR, so no switchback needed, start normal plan now - ; (first cycle omits gas needs calculation in OC without delayed ascent) - - ; switch back to loop calculation if last cycle was doing a bailout calculation -calc_deko_divemode2a: - movff opt_calc_asc_gasvolume,hi ; get the gas volume needs calculation setting - movf hi,W ; are gas volume calculations turned on? - bz calc_deko_divemode2e ; NO - can't have done a bailout calculation then, start normal plan - btfsc is_bailout ; YES - check if a real bailout situation is present - bra calc_deko_divemode2e ; YES - OC gases have been set by bailout action then, start normal plan - movff active_gas,WREG ; NO - switch back to loop calculation: get current (diluent) gas, ... - call deco_setup_cc_diluents ; ... set up deco calculations in CCR/pSCR mode with diluents, - bra calc_deko_divemode2e ; ... and start in normal plan mode - - ; The PLAN bit was cleared, i.e. a normal plan was computed in the last cycle. For the next - ; computation cycle the mode may be switched to alternative plan, or stay in normal mode... - -calc_deko_divemode2b: - bcf lo,DECO_ASCENT_FLAG ; clear flag for delayed ascent calculation (for safety only) - btfsc is_bailout ; check if a real bailout situation is present - bra calc_deko_divemode2c ; YES - stay in normal plan mode and preclude delayed ascent calculation - movff char_I_extra_time,hi ; NO - get the delayed ascent setting - tstfsz hi ; check if delayed ascent calculation is enabled - bsf lo,DECO_ASCENT_FLAG ; YES - set flag for delayed ascent calculation - tstfsz hi ; check if delayed ascent calculation is enabled (again) - bsf lo,DECO_PLAN_FLAG ; YES - set flag for alternative plan - - ; check if a gas needs calculation shall be done -calc_deko_divemode2c: - bsf lo,DECO_VOLUME_FLAG ; set gas needs calculation flag (may be cleared again next) - TSTOSS opt_calc_asc_gasvolume ; check if gas needs calculation is enabled - bcf lo,DECO_VOLUME_FLAG ; NO - reset flag again - movff lo,char_O_deco_status ; write-back char_O_deco_status to deco engine interface - TSTOSS opt_calc_asc_gasvolume ; check if gas volume calculation is enabled (again) - bra calc_deko_divemode2e ; NO - no volume calculation, no simulated bailout plan in no case - - ; check if conditions are met to calculate a bailout plan - btfsc is_bailout ; check if a real bailout situation is present - bra calc_deko_divemode2e ; YES - normal plan already does bailout (OC) calculation "for real" - btfss lo,DECO_MODE_LOOP_FLAG ; NO - have loop mode calculation been done during the normal plan? - bra calc_deko_divemode2e ; NO - when not in loop mode, no simulated bailout to be done - bsf lo,DECO_PLAN_FLAG ; YES - set flag for alternative plan - movff lo,char_O_deco_status ; write-back char_O_deco_status to deco engine interface - call get_first_gas_to_WREG ; get first OC gas, ... - call deco_setup_oc_gases ; ... set up deco calculations in OC mode with OC gases, - ;bra calc_deko_divemode2e ; ... and start in alternative plan mode - - -calc_deko_divemode2e: - clrf TMR5L - clrf TMR5H ; 30,51757813µs/bit in TMR5L:TMR5H - call deco_calc_hauptroutine ; calc_tissue +calc_deko_engine_cont: + SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; transfer ambient pressure to deco engine + clrf TMR5L ; restart timer used to preempt stops calculation + clrf TMR5H ; + call deco_calc_hauptroutine ; invoke the deco engine (p2_deco.c) banksel common - ; Check if deco stops are necessary - movff char_O_first_deco_depth,WREG; get ceiling - tstfsz WREG ; ceiling < 0m (aka in deco) ? - bra calc_deko_divemode3 ; YES - ; NO - within NDL - btfsc decostop_active ; already in no deco mode ? - bsf FLAG_TFT_display_ndl_mask ; NO - clear deco data, display NDL time + ; check if display shall be updated due to deco engine restart + btfsc FLAG_TFT_display_ndl_or_deko; shall update immediately? + bra calc_deko_engine_update ; YES + + ; check if new calculation results for normal plan mode are available + movff char_O_main_status,WREG ; get deco status of deco engine + btfss WREG,DECO_COMPLETED_NORM ; new calculation results for normal plan available? + return ; NO - done +calc_deko_engine_update: + bcf FLAG_TFT_display_ndl_or_deko; YES - reset flag for immediate update + movff char_O_deco_info,WREG ; - get deco info vector + btfsc WREG,deco_ceiling ; - ceiling depth > 0 ? + bra calc_deko_engine_update_deco; YES - in deco + ;bra calc_deko_engine_update_NDL ; NO - within NDL + +calc_deko_engine_update_NDL: ; within NDL + btfsc decostop_active ; been in deco mode before? + bsf FLAG_TFT_display_ndl_mask ; YES - clear deco data, display NDL time bsf FLAG_TFT_display_ndl ; display NDL time - bcf decostop_active ; clear flag (again) + bcf decostop_active ; clear flag for been in deco mode before return -calc_deko_divemode3: - ; YES - in deco - btfss decostop_active ; already in deco mode ? +calc_deko_engine_update_deco: ; in deco + btfss decostop_active ; already been in deco mode before? bsf FLAG_TFT_display_deko_mask ; NO - clear NDL time, display deco data bsf FLAG_TFT_display_deko ; display deco data bsf FLAG_TFT_display_tts ; display TTS - bsf decostop_active ; set flag (again) + bsf decostop_active ; set flag for being in deco mode return ; -------------------------------------------------------------------------------------- @@ -521,71 +590,57 @@ btfss s8_digital ; check if we have a digital interface to the sensors bra calc_deko_divemode_sensor_analog ; NO - check if we have an analog interface btfss new_s8_data_available ; YES - check if a new data frame was received - bra calc_deko_divemode_sensor_common ; NO - use old values -- TODO: add timeout for no new data + bra calc_deko_divemode_sensor_common ; NO - use old values call compute_mvolts_for_all_sensors ; YES - compute mV values from digital data bra calc_deko_divemode_sensor_common - +calc_deko_divemode_sensor_analog: + btfss analog_o2_input ; do we have an analog input? + bra calc_deko_divemode_sensor_opt ; NO - check if we have an optical interface + call get_analog_inputs ; YES - get the analog voltages and continue with the common part + bra calc_deko_divemode_sensor_common calc_deko_divemode_sensor_opt: - btfss optical_input ; do we have an optical input? - return ; No, return (We have no sensors at all. Not analog, not S8 and not optical) - ;o2_ppo2_sensor1, o2_ppo2_sensor2 and o2_ppo2_sensor3 are already filled in ISR - ;clear use_O2_sensorX for timeout case - btfss sensor1_active - bcf use_O2_sensor1 - btfss sensor2_active - bcf use_O2_sensor2 + btfss optical_input ; do we have an optical input? + return ; NO - return (we have no sensors at all: not analog, not S8 and not optical) + btfss sensor1_active ; YES - o2_ppo2_sensor1, o2_ppo2_sensor2 and o2_ppo2_sensor3 are already filled in ISR + bcf use_O2_sensor1 ; check HUD status data and eventually clear use_O2_sensorX + btfss sensor2_active + bcf use_O2_sensor2 btfss sensor3_active - bcf use_O2_sensor3 - bra calc_deko_divemode_sensor1 - -calc_deko_divemode_sensor_analog: - btfss analog_o2_input ; do we have an analog input? - bra calc_deko_divemode_sensor_opt ; NO - check if we have an optical interface - call get_analog_inputs ; YES - get the analog voltages and continue with the common part + bcf use_O2_sensor3 + bra calc_deko_divemode_sensor_A ; continue with calculating sensor average calc_deko_divemode_sensor_common: - ; Check for each sensor if it is calibrated and if its mv value is within min_mv and max_mv limits. - ; If ok: compute o2_ppo2_sensorX := o2_mv_sensorX * opt_x_sX / 1000 + ; Check each sensor if it is calibrated and if its mV value is within min_mv and max_mv limits. + ; If ok: compute o2_ppo2_sensorX = o2_mv_sensorX * opt_x_sX / 1000 ; If not ok: reset o2_ppo2_sensorX, reset use_O2_sensorX and show the customview 1 in case the sensor was ok before - ; Check min_mv of sensor 1 + ; check sensor 1 btfss sensor1_calibrated_ok ; check if sensor is usable at all bra check_sensor_1_fail ; NO - handle it as failed - movff o2_mv_sensor1+0, sub_a+0 ; load sensor mV value - movff o2_mv_sensor1+1, sub_a+1 - movlw LOW min_mv ; load minimum mV value - movwf sub_b+0 - movlw HIGH min_mv - movwf sub_b+1 - call sub16 ; sub_c = sensor_mv - min_mv + ; check min threshold + movff o2_mv_sensor1+0,sub_a+0 ; load sensor mV value + movff o2_mv_sensor1+1,sub_a+1 + rcall check_min_threshold btfsc neg_flag ; check if result is negative, i.e. sensor_mv < min_mv bra check_sensor_1_fail ; YES - declare sensor as failed - ; Check max_mv of sensor 1 ; NO - continue with next check - movff o2_mv_sensor1+0, sub_a+0 - movff o2_mv_sensor1+1, sub_a+1 - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 - call sub16 ; sub_c = sensor_mv - max_mv + ; check max_threshold + rcall check_max_threshold btfss neg_flag ; check if result is negative, i.e. sensor_mv < max_mv bra check_sensor_1_fail ; NO - declare sensor as failed - ; Check HUD data, if available ; YES - continue with next check + ; check HUD data, if available btfss hud_connection_ok ; check if there is a HUD connected bra check_sensor_1_ok ; NO - all checks done then and positive - btfss sensor1_active ; YES - check HUD report on sensor - bra check_sensor_1_fail ; HUD reports a fail - + btfss sensor1_active ; YES - HUD status ok? + bra check_sensor_1_fail ; NO - HUD reports a fail check_sensor_1_ok: - ; o2_ppo2_sensor1 := o2_mv_sensor1:2 * opt_x_s1:2 / 1000 + ; o2_ppo2_sensor1 = o2_mv_sensor1:2 * opt_x_s1:2 / 1000 movff o2_mv_sensor1+0,xA+0 movff o2_mv_sensor1+1,xA+1 movff opt_x_s1+0,xB+0 movff opt_x_s1+1,xB+1 rcall compute_ppo2_helper - movff xC+0,o2_ppo2_sensor1 ; result in 0.01bar + movff xC+0,o2_ppo2_sensor1 ; result in 0.01 bar bra check_sensor_2 ; continue with next sensor - check_sensor_1_fail: clrf WREG movff WREG,o2_ppo2_sensor1 ; set ppO2 reading to zero @@ -594,46 +649,34 @@ call check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met check_sensor_1_fail_1: bcf use_O2_sensor1 ; revoke sensor from usage - ;bra check_sensor_2 ; continue with next sensor - -check_sensor_2: ; Check min_mv of sensor 2 + +check_sensor_2: ; check min_mv of sensor 2 btfss sensor2_calibrated_ok ; check if sensor is usable at all bra check_sensor_2_fail ; NO - handle it as failed - movff o2_mv_sensor2+0, sub_a+0 ; load sensor mV value - movff o2_mv_sensor2+1, sub_a+1 - movlw LOW min_mv ; load minimum mV value - movwf sub_b+0 - movlw HIGH min_mv - movwf sub_b+1 - call sub16 ; sub_c = sensor_mv - min_mv + ; check min threshold + movff o2_mv_sensor2+0,sub_a+0 ; load sensor mV value + movff o2_mv_sensor2+1,sub_a+1 + rcall check_min_threshold btfsc neg_flag ; check if result is negative, i.e. sensor_mv < min_mv bra check_sensor_2_fail ; YES - declare sensor as failed - ; Check max_mv of sensor 2 ; NO - continue with next check - movff o2_mv_sensor2+0, sub_a+0 - movff o2_mv_sensor2+1, sub_a+1 - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 - call sub16 ; sub_c = sensor_mv - max_mv + ; check max_threshold + rcall check_max_threshold btfss neg_flag ; check if result is nagative, i.e. sensor_mv < max_mv bra check_sensor_2_fail ; NO - declare sensor as failed - ; Check HUD data, if available ; YES - continue with next check + ; check HUD data, if available btfss hud_connection_ok ; check if there is a HUD connected bra check_sensor_2_ok ; NO - all checks done then and positive - btfss sensor2_active ; YES - check HUD report on sensor - bra check_sensor_2_fail ; HUD reports a fail - + btfss sensor2_active ; YES - HUD status ok? + bra check_sensor_2_fail ; NO - HUD reports a fail check_sensor_2_ok: - ; o2_ppo2_sensor2 := o2_mv_sensor2:2 * opt_x_s2:2 / 1000 + ; o2_ppo2_sensor2 = o2_mv_sensor2:2 * opt_x_s2:2 / 1000 movff o2_mv_sensor2+0,xA+0 movff o2_mv_sensor2+1,xA+1 movff opt_x_s2+0,xB+0 movff opt_x_s2+1,xB+1 rcall compute_ppo2_helper - movff xC+0,o2_ppo2_sensor2 ; result in 0.01bar + movff xC+0,o2_ppo2_sensor2 ; result in 0.01 bar bra check_sensor_3 ; continue with next sensor - check_sensor_2_fail: clrf WREG movff WREG,o2_ppo2_sensor2 ; set ppO2 reading to zero @@ -642,186 +685,191 @@ call check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met check_sensor_2_fail_1: bcf use_O2_sensor2 ; revoke sensor from usage - ;bra check_sensor_3 ; continue with next sensor - -check_sensor_3: ; Check min_mv of sensor 2 + +check_sensor_3: ; check min_mv of sensor 2 btfss sensor3_calibrated_ok ; check if sensor is usable at all bra check_sensor_3_fail ; NO - handle it as failed - movff o2_mv_sensor3+0, sub_a+0 ; load sensor mV value - movff o2_mv_sensor3+1, sub_a+1 - movlw LOW min_mv ; load minimum mV value - movwf sub_b+0 - movlw HIGH min_mv - movwf sub_b+1 - call sub16 ; sub_c = sensor_mv - min_mv + ; check min threshold + movff o2_mv_sensor3+0,sub_a+0 ; load sensor mV value + movff o2_mv_sensor3+1,sub_a+1 + rcall check_min_threshold btfsc neg_flag ; check if result is negative, i.e. sensor_mv < min_mv bra check_sensor_3_fail ; YES - declare sensor as failed - ; Check max_mv of sensor 2 ; NO - continue with next check - movff o2_mv_sensor3+0, sub_a+0 - movff o2_mv_sensor3+1, sub_a+1 - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 - call sub16 ; sub_c = sensor_mv - max_mv + ; check max threshold + rcall check_max_threshold btfss neg_flag ; check if result is negative, i.e. sensor_mv < max_mv bra check_sensor_3_fail ; NO - declare sensor as failed - ; Check HUD data, if available ; YES - continue with next check + ; check HUD data, if available btfss hud_connection_ok ; check if there is a HUD connected bra check_sensor_3_ok ; NO - all checks done then and positive - btfss sensor3_active ; YES - check HUD report on sensor - bra check_sensor_3_fail ; HUD reports a fail - + btfss sensor3_active ; YES - HUD status ok? + bra check_sensor_3_fail ; NO - HUD reports a fail check_sensor_3_ok: - ; o2_ppo2_sensor3 := o2_mv_sensor3:2 * opt_x_s1:2 / 1000 + ; o2_ppo2_sensor3 = o2_mv_sensor3:2 * opt_x_s1:2 / 1000 movff o2_mv_sensor3+0,xA+0 movff o2_mv_sensor3+1,xA+1 movff opt_x_s3+0,xB+0 movff opt_x_s3+1,xB+1 rcall compute_ppo2_helper - movff xC+0,o2_ppo2_sensor3 ; result in 0.01bar - bra calc_deko_divemode_sensor1 ; continue with calculating sensor average - + movff xC+0,o2_ppo2_sensor3 ; result in 0.01 bar + bra calc_deko_divemode_sensor_A ; continue with calculating sensor average check_sensor_3_fail: clrf WREG movff WREG,o2_ppo2_sensor3 ; set ppO2 reading to zero btfss use_O2_sensor3 ; check if sensor was in use before bra check_sensor_3_fail_1 ; NO - no new news then - call check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met + call check_sensor_custview_helper; YES - show custom view 1 (sensor values) on further conditions met check_sensor_3_fail_1: bcf use_O2_sensor3 ; revoke sensor from usage - ;bra calc_deko_divemode_sensor1 ; continue with calculating sensor average - -calc_deko_divemode_sensor1: ; calculate sensor average - ; exit here if not in divemode + +calc_deko_divemode_sensor_A: ; calculate sensor average + ; exit here if not in dive mode btfss divemode return - ; compute sensor_setpoint := average of all o2_ppo2_sensorX of those sensors that have use_O2_sensorX == true + ; compute sensor_setpoint = average of all o2_ppo2_sensorX of those sensors that have use_O2_sensorX == true ; sum up sensor values (in xA:2) and active sensors in (xB:2) clrf xB+0 clrf xB+1 clrf xA+0 clrf xA+1 - btfss use_O2_sensor1 ; Sensor1 active? - bra divemode_setup_sensor_values2 ; No +divemode_setup_sensor_1_value: + btfss use_O2_sensor1 ; sensor1 active? + bra divemode_setup_sensor_2_value ; NO movf o2_ppo2_sensor1,W - addwf xA+0 + addwf xA+0,F movlw .0 - addwfc xA+1 ; Add into xA:2 - incf xB+0,F ; Add a sensor -divemode_setup_sensor_values2: - btfss use_O2_sensor2 ; Sensor2 active? - bra divemode_setup_sensor_values3 ; No + addwfc xA+1,F ; add into xA:2 + incf xB+0,F ; add a sensor +divemode_setup_sensor_2_value: + btfss use_O2_sensor2 ; sensor2 active? + bra divemode_setup_sensor_3_value ; NO movf o2_ppo2_sensor2,W - addwf xA+0 + addwf xA+0,F movlw .0 - addwfc xA+1 ; Add into xA:2 - incf xB+0,F ; Add a sensor -divemode_setup_sensor_values3: - btfss use_O2_sensor3 ; Sensor3 active? - bra divemode_setup_sensor_values4 ; No + addwfc xA+1,F ; add into xA:2 + incf xB+0,F ; add a sensor +divemode_setup_sensor_3_value: + btfss use_O2_sensor3 ; sensor3 active? + bra divemode_setup_sensor_mean ; NO movf o2_ppo2_sensor3,W - addwf xA+0 + addwf xA+0,F movlw .0 - addwfc xA+1 ; Add into xA:2 - incf xB+0,F ; Add a sensor - - ; Divide sum of sensor values by number of active sensors found. -divemode_setup_sensor_values4: - call div16x16 ; xA/xB=xC with xA+0 as remainder - movff xC+0,sensor_setpoint ; copy result - - ; set default value for pSCR mode: 0 = let p2_deco.c compute the ppO2 based on current dil gas and depth + addwfc xA+1,F ; add into xA:2 + incf xB+0,F ; add a sensor + + ; divide sum of sensor values by number of active sensors found +divemode_setup_sensor_mean: + clrf xC+0 ; set zero as default result + tstfsz xB+0 ; pending div/0 ? + call div16x16 ; NO - execute xC = xA / xB = summed ppO2 / number of sensors + movff xC+0,sensor_setpoint ; copy result (or its default) + + ; set default value for pSCR mode: 0 => let p2_deco.c compute the ppO2 based on current dil gas and depth ; will be overwritten later in case we are in sensor mode and have at least one usable sensor - clrf WREG ; preload a zero - btfsc FLAG_pscr_mode ; check if we are in pSCR mode - movff WREG,char_I_const_ppO2 ; YES - write 0 to char_I_const_ppo2, - ; it will be overwritten if we have a usable sensor reading - - btfsc is_bailout ; check if we are in bailout - bra calc_deko_divemode_sensor2 ; YES - no sensor data transfer to char_I_const_ppO2 in this case - movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP - sublw .1 ; opt_ccr_mode = 1 (Sensor)? - bnz calc_deko_divemode_sensor2 ; not in sensor mode - no transfer of sensor data to char_I_const_ppO2 - tstfsz xB+0 ; check if we have found at least one usable sensor - bra calc_deko_divemode_sensor1a ; YES - we have at least one usable sensor - bsf setpoint_fallback ; NO - we have NO usable sensors -> initiate fallback - btfss FLAG_ccr_mode ; check if we are in CCR mode - bra calc_deko_divemode_sensor2 ; NO - continue with voting logic flags - movff char_I_setpoint_cbar+0,char_I_const_ppO2 ; YES - select fixed setpoint no. 1 for fallback - bra calc_deko_divemode_sensor2 ; done - continue with voting logic flags -calc_deko_divemode_sensor1a: ; we have at least one usable sensor with a value > 0 - bcf setpoint_fallback ; clear fallback condition + clrf WREG ; preload a zero + btfsc FLAG_pscr_mode ; check if we are in pSCR mode + movff WREG,char_I_const_ppO2 ; YES - write 0 to char_I_const_ppo2, + ; it will be overwritten if we have a usable sensor reading + btfsc FLAG_bailout_mode ; check if we are in bailout + bra calc_deko_divemode_sensor_V ; YES - no sensor data transfer to char_I_const_ppO2 in this case + movff opt_ccr_mode,WREG ; NO - get mode (0: Fixed SP, 1: Sensor, 2: Auto SP) + sublw .1 ; - in sensor mode? + bnz calc_deko_divemode_sensor_V ; NO - not in sensor mode - no transfer of sensor data to char_I_const_ppO2 + tstfsz xB+0 ; YES - check if we have found at least one usable sensor + bra divemode_setup_sensor_mean1 ; YES - we have at least one usable sensor + bsf setpoint_fallback ; NO - we have NO usable sensors -> initiate fallback + btfss FLAG_ccr_mode ; - check if we are in CCR mode + bra calc_deko_divemode_sensor_V ; NO - continue with voting logic flags + movff char_I_setpoint_cbar+0,char_I_const_ppO2; YES - select fixed setpoint no. 1 for fallback + bra calc_deko_divemode_sensor_V ; - continue with voting logic flags + ; we have at least one usable sensor with a ppO2 value > 0 +divemode_setup_sensor_mean1: + bcf setpoint_fallback ; clear fallback condition movff sensor_setpoint,char_I_const_ppO2 ; transfer average sensor value to p2_deco.c code - ;bra calc_deko_divemode_sensor2 - -calc_deko_divemode_sensor2: + ; vote sensors +calc_deko_divemode_sensor_V: bsf voting_logic_sensor1 movff o2_ppo2_sensor1,lo rcall check_sensor_voting_helper - incfsz WREG ; Was WREG = 255? - bcf voting_logic_sensor1 ; No, ignore this sensor + tstfsz WREG ; sensor within range (WREG = 0)? + bcf voting_logic_sensor1 ; NO - vote out this sensor bsf voting_logic_sensor2 movff o2_ppo2_sensor2,lo rcall check_sensor_voting_helper - incfsz WREG ; Was WREG=255? - bcf voting_logic_sensor2 ; No, ignore this sensor + tstfsz WREG ; sensor within range (WREG = 0)? + bcf voting_logic_sensor2 ; NO - vote out this sensor bsf voting_logic_sensor3 movff o2_ppo2_sensor3,lo rcall check_sensor_voting_helper - incfsz WREG ; Was WREG=255? - bcf voting_logic_sensor3 ; No, ignore this sensor + tstfsz WREG ; sensor within range (WREG = 0)? + bcf voting_logic_sensor3 ; NO - vote out this sensor ; check if a warning shall be issued on sensor disagreement - btfsc FLAG_ccr_mode ; check if we are in CCR mode - bra check_warn_sensor_1 ; YES - continue with further checks + bra check_warn_sensor_0 ; YES - continue with further checks btfsc FLAG_pscr_mode ; check if we are in pSCR mode - bra check_warn_sensor_1 ; YES - continue with further checks - bra check_warn_sensor_agree ; not in CCR and not in pSCR, so no warning -check_warn_sensor_1: ; we are in CCR or pSCR mode - btfsc is_bailout ; check if we are in bailout - bra check_warn_sensor_agree ; YES - no warning in this case - movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP - sublw .1 ; opt_ccr_mode = 1 (Sensor)? - bnz check_warn_sensor_agree ; not in sensor mode - no warning in this case - ; check sensor 1 + bra check_warn_sensor_0 ; YES - continue with further checks + bra check_warn_sensor_done ; not in CCR and not in pSCR, so no warning +check_warn_sensor_0: ; we are in CCR or pSCR mode + btfsc FLAG_bailout_mode ; check if we are in bailout + bra check_warn_sensor_done ; YES - no warning in this case + movff opt_ccr_mode,WREG ; get mode (0: Fixed SP, 1: Sensor, 2: Auto SP) + sublw .1 ; in sensor mode? + bnz check_warn_sensor_done ; NO - not in sensor mode - no warning in this case + ; check sensor 1 +check_warn_sensor_1: btfss sensor1_calibrated_ok ; check if sensor has a valid calibration bra check_warn_sensor_2 ; NO - sensor can not cause a warning then btfss use_O2_sensor1 ; YES - check if sensor is in use - bra check_warn_sensor_2 ; NO - sensor can not cause a warning then - btfsc voting_logic_sensor1 ; YES - check if sensor value is within agreement range - bra check_warn_sensor_2 ; YES - continue with next sensor - bcf sensors_agree ; NO - issue a warning + bra check_warn_sensor_2 ; NO - sensor can not cause a warning then + btfsc voting_logic_sensor1 ; YES - check if sensor value is within agreement range + bra check_warn_sensor_2 ; YES - continue with next sensor + bcf sensors_agree ; NO - issue a warning return - -check_warn_sensor_2: ; check sensor 2 + ; check sensor 2 +check_warn_sensor_2: btfss sensor2_calibrated_ok ; check if sensor has a valid calibration bra check_warn_sensor_3 ; NO - sensor can not cause a warning then btfss use_O2_sensor2 ; YES - check if sensor is in use - bra check_warn_sensor_3 ; NO - sensor can not cause a warning then - btfsc voting_logic_sensor2 ; YES - check if sensor value is within agreement range - bra check_warn_sensor_3 ; YES - continue with next sensor - bcf sensors_agree ; NO - issue a warning + bra check_warn_sensor_3 ; NO - sensor can not cause a warning then + btfsc voting_logic_sensor2 ; YES - check if sensor value is within agreement range + bra check_warn_sensor_3 ; YES - continue with next sensor + bcf sensors_agree ; NO - issue a warning return - -check_warn_sensor_3: ; check sensor 2 + ; check sensor 3 +check_warn_sensor_3: btfss sensor3_calibrated_ok ; check if sensor has a valid calibration bra check_warn_sensor_agree ; NO - sensor can not cause a warning then btfss use_O2_sensor3 ; YES - check if sensor is in use - bra check_warn_sensor_agree ; NO - sensor can not cause a warning then - btfsc voting_logic_sensor3 ; YES - check if sensor value is within agreement range - bra check_warn_sensor_agree ; YES - continue with next sensor - bcf sensors_agree ; NO - issue a warning + bra check_warn_sensor_agree ; NO - sensor can not cause a warning then + btfsc voting_logic_sensor3 ; YES - check if sensor value is within agreement range + bra check_warn_sensor_agree ; YES - continue with next sensor + bcf sensors_agree ; NO - issue a warning return - + ; no need for a warning +check_warn_sensor_done: check_warn_sensor_agree: bsf sensors_agree return + +check_min_threshold: + movlw LOW min_mv ; load minimum mV value + movwf sub_b+0 + movlw HIGH min_mv + movwf sub_b+1 + goto sub16 ; sub_c = sensor_mv - min_mv (and return) + +check_max_threshold: + movlw LOW max_mv + movwf sub_b+0 + movlw HIGH max_mv + movwf sub_b+1 + goto sub16 ; sub_c = sensor_mv - max_mv (and return) + compute_ppo2_helper: call mult16x16 ; xA:2*xB:2=xC:4 movlw LOW .1000 @@ -834,75 +882,83 @@ movlw d'0' addwfc xC+1,W ; we are still just interested in the carry flag tstfsz WREG ; ppO2 is higher than 2.55bar? - setf xC+0 ; Yes. + setf xC+0 ; YES return check_sensor_custview_helper: - btfss divemode ; check if we are in divemode + btfss divemode ; check if we are in dive mode return ; NO - not in dive mode, return - movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP - sublw .1 ; opt_ccr_mode = 1 (Sensors)? - bnz check_sensor_helper_1 ; NO - not using the sensors in the moment - clrf menupos3 ; YES - arm customview 1 (sensor values) - bsf toggle_customview ; and request a customview toggle -check_sensor_helper_1: + movff opt_ccr_mode,WREG ; YES - =0: Fixed SP, =1: Sensor, =2: Auto SP + decfsz WREG,W ; - opt_ccr_mode = 1 (sensors)? + return ; NO - not using the sensors in the moment + btfsc alternative_divelayout ; YES - in alternative layout? + call switch_layout_to_normal ; YES - switch to normal layout + movlw index_ppo2_sensors-1 ; custom view number one below ppO2 sensors + movwf menupos3 ; set custom view number + bsf toggle_customview ; initiate toggle to desired custom view -> ppO2 sensors return - check_sensor_voting_helper: movf lo,W cpfsgt sensor_setpoint - bra check_sensor_voting_common2 ; lo < sensor_setpoint + bra check_sensor_voting_helper2 ; lo < sensor_setpoint ; lo > sensor_setpoint movf lo,W subwf sensor_setpoint,W movwf lo -check_sensor_voting_common1: - movlw sensor_voting_logic_threshold ; Threshold in 0.01 bar +check_sensor_voting_helper1: + movlw sensor_voting_logic_threshold ; threshold in 0.01 bar cpfsgt lo - retlw .255 ; Within range - retlw .0 ; Out of range -check_sensor_voting_common2: - ; lo<sensor_setpoint + retlw .0 ; within range + retlw .1 ; out of range +check_sensor_voting_helper2: + ; lo < sensor_setpoint movf sensor_setpoint,W subwf lo,F - bra check_sensor_voting_common1 + bra check_sensor_voting_helper1 ;----------------------------------------------------------------------------- -divemodemode_togglegf: ; Toggle aGF/GF - bcf toggle_gf ; clear flag - btg use_agf ; toggle GF - - btfsc use_agf ; switch to aGF? +divemodemode_togglegf: ; toggle aGF/GF + bcf toggle_gf ; clear command flag + btg use_agf ; toggle status flag for GF + + btfsc use_agf ; aGF activated? bra divemodemode_togglegf_1 ; YES - branch to using aGF movff opt_GF_low,char_I_GF_Low_percentage ; NO - use normal GF factors - movff opt_GF_high,char_I_GF_High_percentage ; - bra divemodemode_togglegf_2 ; continue with common part - -divemodemode_togglegf_1: ; use alternative GF factors - movff opt_aGF_low,char_I_GF_Low_percentage - movff opt_aGF_high,char_I_GF_High_percentage - + movff opt_GF_high,char_I_GF_High_percentage ; - + bra divemodemode_togglegf_2 ; - continue with common part +divemodemode_togglegf_1: + movff opt_aGF_low,char_I_GF_Low_percentage ; YES - use alternative GF factors + movff opt_aGF_high,char_I_GF_High_percentage ; - divemodemode_togglegf_2: - call TFT_gf_mask ; update customview mask to show which one is in use - ; the customview itself has been called from divemenu_tree before + call TFT_gf_factors_mask ; update custom view mask to show which one is in use + ; the custom view itself has been called from divemenu_tree before goto restart_deco_engine ; ...and return -calc_velocity: ; called every two seconds + IFDEF _cave_mode +divemodemode_toggleturn: + bcf toggle_turn_dive ; clear command flag + btg FLAG_dive_turned ; toggle dive turned state + btfsc FLAG_cave_mode_shutdown ; cave mode function shut down? + bsf FLAG_dive_turned ; YES - allow only activating turned state + goto set_logbook_marker ; set a logbook marker (and return) + ENDIF + +calc_velocity: ; called every two seconds btfsc display_velocity - bra calc_velocity1 ; Always update if already displayed + bra calc_velocity1 ; always update if already displayed btfss divemode2 - return ; display velocity only if deeper then 1m (Not at the surface after the dive) + return ; display velocity only if deeper then 1m (Not at the surface after the dive) calc_velocity1: SAFE_2BYTE_COPY amb_pressure, sub_a movff last_pressure_velocity+0,sub_b+0 movff last_pressure_velocity+1,sub_b+1 - movff sub_a+0,last_pressure_velocity+0 ; store old value for velocity + movff sub_a+0,last_pressure_velocity+0 ; store old value for velocity movff sub_a+1,last_pressure_velocity+1 - call subU16 ; sub_c = amb_pressure - last_pressure + call subU16 ; sub_c = amb_pressure - last_pressure bcf neg_flag_velocity btfsc neg_flag @@ -917,13 +973,12 @@ movff xC+0,divA+0 movff xC+1,divA+1 movlw d'7' - movwf divB+0 - call div16 ; divided by 2^7 equals velocity in m/min + call div16 ; divA = divA / 2^WREG, divide by 2^7 equals velocity in m/min movlw d'99' - cpfsgt divA+0 ; limit to 99m/min - bra calc_velocity3 - movwf divA+0 ; divA=99 + cpfsgt divA+0 ; velocity > 99 m/min ? + bra calc_velocity3 ; NO + movwf divA+0 ; YES - set divA = 99 calc_velocity3: ; Copy old speeds @@ -948,19 +1003,19 @@ ; addwf divA+0,F ; add old speed ; bcf STATUS,C ; rrcf divA+0,F ; /2 - goto TFT_display_velocity ; With divA+0 = m/min..., and return... + goto TFT_display_velocity ; with divA+0 = m/min..., and return... ;============================================================================= -set_reset_safety_stop: ; Set flags for safety stop and/or reset safety stop - TSTOSS opt_enable_safetystop ; =1: A safety stop is shown - bra delete_safety_stop ; No, don't show safety stop - - btfsc decostop_active ; Is a deco stop displayed? - bra delete_safety_stop ; Yes, don't show safety stop - - ; Below "opt_safety_stop_reset"? Set flag and reset count-down timer +set_reset_safety_stop: ; set flags for safety stop and/or reset safety stop + TSTOSS opt_enable_safetystop ; safety stop enabled? (=1: show safety stop) + bra delete_safety_stop ; NO - don't show safety stop + + btfsc decostop_active ; is a deco stop displayed? + bra delete_safety_stop ; YES - don't show safety stop + + ; Below "opt_safety_stop_reset"? if yes, set flag and reset count-down timer SAFE_2BYTE_COPY rel_pressure, lo call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] movff lo,sub_a+0 @@ -971,51 +1026,43 @@ movff PRODH,sub_b+1 call subU16 ; sub_c = sub_a - sub_b btfss neg_flag - bra reset_safety_stop ; Below 10m, reset safety stop - - ; Above "opt_safety_stop_end"? Clear flag. - SAFE_2BYTE_COPY rel_pressure, lo - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - movff lo,sub_a+0 - movff hi,sub_a+1 + bra reset_safety_stop ; below 10m, reset safety stop + + ; Above "opt_safety_stop_end"? if yes ,clear flag movff opt_safety_stop_end,WREG ; [cbar] mullw .10 ; mbar in PRODL:H - movff PRODL,sub_b+0 + movff PRODL,sub_b+0 ; sub_a is still loaded with adjusted rel_pressure movff PRODH,sub_b+1 call subU16 ; sub_c = sub_a - sub_b btfsc neg_flag - bra delete_safety_stop ; Above 3m, remove safety stop - - ; Above "opt_safety_stop_start"? Activate safety stop - SAFE_2BYTE_COPY rel_pressure, lo - call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] - movff lo,sub_a+0 - movff hi,sub_a+1 + bra delete_safety_stop ; above 3m, remove safety stop + + ; Above "opt_safety_stop_start"? if yes, activate safety stop movff opt_safety_stop_start,WREG ; [cbar] mullw .10 ; mbar in PRODL:H - movff PRODL,sub_b+0 + movff PRODL,sub_b+0 ; sub_a is still loaded with adjusted rel_pressure movff PRODH,sub_b+1 call subU16 ; sub_c = sub_a - sub_b btfsc neg_flag - bra acivate_safety_stop ; Above 5m, activate safety stop - bra reset_safety_stop2 ; Pause safety stop + bra acivate_safety_stop ; above 5m, activate safety stop + bra reset_safety_stop2 ; pause safety stop acivate_safety_stop: - tstfsz safety_stop_countdown ; Countdown at zero? - bsf show_safety_stop ; No, Set flag! + tstfsz safety_stop_countdown ; countdown at zero? + bsf show_safety_stop ; NO - set flag return delete_safety_stop: clrf safety_stop_countdown ; reset timer - bra reset_safety_stop2 ; Remove safety stop from display + bra reset_safety_stop2 ; remove safety stop from display reset_safety_stop: movff opt_safety_stop_length,safety_stop_countdown ; reset timer reset_safety_stop2: - bcf show_safety_stop ; Clear flag - btfss safety_stop_active ; Safety stop shown - return ; No, don't delete it - bcf safety_stop_active ; Clear flag + bcf show_safety_stop ; clear flag + btfss safety_stop_active ; safety stop shown? + return ; NO - don't delete it + bcf safety_stop_active ; clear flag bsf FLAG_TFT_clear_safety_stop ; Clear safety stop return @@ -1023,27 +1070,28 @@ ;============================================================================= timeout_menuview: - decfsz timeout_counter2,F ; timeout for menuview - return ; No timeout, return + decfsz timeout_counter2,F ; timeout for menu view? + return ; NO - done ; Timeout, clear e.g. "Menu?" - goto menuview_toggle_reset ; "returns" + goto menuview_toggle_reset ; ...and return timeout_divemode_menu: decfsz timeout_counter2,F ; timeout for divemode menu return global timeout_divemode_menu2 -timeout_divemode_menu2: ; Called from divemenu_tree.asm - bcf divemode_menu ; Timeout! Clear flag - call TFT_clear_divemode_menu ; Clear menu - bsf FLAG_TFT_active_gas_divemode; Redraw gas/setpoint/diluent - bcf blinking_better_gas ; Clear flag to have temperature updated once - bsf FLAG_TFT_temp_divemode ; Displays temperature - call TFT_draw_gassep_line ; Gas separator grid in spec mode only - - btfss decostop_active ; In deco mode ? - bra timeout_divemode_menu_ndl ; No, show NDL again - ; Show deco +timeout_divemode_menu2: ; called from divemenu_tree.asm + bcf divemode_menu ; timeout, clear flag + call TFT_clear_divemode_menu ; clear menu + bsf FLAG_TFT_active_gas_divemode; redraw gas/setpoint/diluent + bcf blinking_better_gas ; clear flag to have temperature updated once + bcf blinking_better_dil ; clear flag to have temperature updated once + bsf FLAG_TFT_temp_divemode ; display temperature + call TFT_draw_gassep_line ; gas separator grid in spec mode only + + btfss decostop_active ; in deco mode ? + bra timeout_divemode_menu_ndl ; NO - show NDL again + ; Show deco data bsf FLAG_TFT_display_deko_mask bsf FLAG_TFT_display_deko bsf FLAG_TFT_display_tts @@ -1056,37 +1104,37 @@ return timeout_divemode: - btfsc divemode_menu ; Divemode menu active? - rcall timeout_divemode_menu ; Yes, check the timeout for it... - - btfsc menuview ; is a menuview shown? - rcall timeout_menuview ; Yes, check the timeout for it... - - btfss realdive ; Dive longer then one minute - return - - btfsc FLAG_apnoe_mode ; In Apnoe mode? - bra timeout_divemode2 ; Yes, use apnoe_timeout [min] for timeout - - ifndef __DEBUG - btfsc simulatormode_active ; In Simulator mode? - bra timeout_divemode3 ; Yes, use simulator timeout - endif - - bcf divemode - infsnz timeout_counter1+0,F + btfsc divemode_menu ; divemode menu active? + rcall timeout_divemode_menu ; YES - check the timeout for it... + + btfsc menuview ; is a menu view shown? + rcall timeout_menuview ; YES - check the timeout for it... + + btfss realdive ; dive longer than one minute? + return ; NO - done + + btfsc FLAG_apnoe_mode ; in apnoe mode? + bra timeout_divemode2 ; YES - use apnoe_timeout [min] for timeout + + IFNDEF __DEBUG + btfsc simulatormode_active ; in simulator mode? + bra timeout_divemode3 ; YES - use simulator timeout + ENDIF + + bcf divemode ; terminate divemode my default + infsnz timeout_counter1+0,F ; increment timeout counter incf timeout_counter1+1,F ; timeout is 16 bit counter - movff opt_diveTimeout,WREG ; in [min] - mullw .60 + movff opt_diveTimeout,WREG ; get timeout in minutes + mullw .60 ; convert into seconds movff PRODL,sub_a+0 - movff PRODH,sub_a+1 ; in [s] + movff PRODH,sub_a+1 movff timeout_counter1+0,sub_b+0 movff timeout_counter1+1,sub_b+1 call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; Result negative? - bsf divemode ; No, set flag + btfss neg_flag ; result negative, i.e. timeout? + bsf divemode ; NO - set divemode flag again return timeout_divemode2: @@ -1113,36 +1161,59 @@ update_divemode60: ; update any minute call get_battery_voltage ; gets battery voltage - rcall set_powersafe ; Battery low? - call customview_minute ; Do every-minute tasks for the custom view area + rcall set_powersafe ; check if battery low + ;call customview_minute ; do every-minute tasks for the custom view area bcf oneminupdate - + IFDEF _cave_mode + movlw .1 ; prepare to add backtrack data for 1 minute + btfsc FLAG_cave_mode ; cave mode enabled? + rcall update_backtrack ; YES - make it so + ENDIF btfss simulatormode_active ; in simulator mode? - return ; No - ; Yes, quite dive mode simulation after 21*256s=89min:36s - movlw .20 - cpfsgt total_divetime_seconds+1 ; Timeout? - return ; No - - ifdef __DEBUG - return ; No simulator timeout in debug mode - endif - - bra divemode_option1 ; Yes, set to 0m and "return" + return ; NO - done + movlw .20 ; YES - quite dive mode simulation after 21 * 256 sec = 89 min : 36 sec + cpfsgt total_divetime_seconds+1 ; timeout? + return ; NO - done + IFDEF __DEBUG + return ; YES - but no timeout in debug mode + ENDIF + bra divemode_option1 ; YES - set depth to 0 m and "return" + + IFDEF _cave_mode +update_backtrack: + btfsc FLAG_dive_turned ; dive turned? + return ; YES - done + movwf lo ; store minutes to add in lo + lfsr FSR1,char_I_backtrack_depth ; load FSR1 with base address of backtrack storage + movff char_I_backtrack_time,FSR1L ; adjust FSR1 to last index +update_backtrack_loop: + btfsc FLAG_cave_mode_shutdown ; backtrack storage full? + return ; YES - done + movff curr_depth,PREINC1 ; NO - increment index and write current depth to backtrack storage + incfsz FSR1L,W ; - did a wrap-around of the index occur (backtrack storage full)? + bra update_backtrack_loop_1 ; NO - continue loop + bsf FLAG_cave_mode_shutdown ; YES - flag backtrack storage as being full + return +update_backtrack_loop_1: + decfsz lo,F ; decrement loop counter, did it became zero? + bra update_backtrack_loop ; NO - loop + movff FSR1L,char_I_backtrack_time ; YES - read-back index + return ; - done + ENDIF set_max_depth: movff max_pressure+0,sub_a+0 movff max_pressure+1,sub_a+1 SAFE_2BYTE_COPY rel_pressure, sub_b call subU16 ; sub_c = sub_a - sub_b - ; max_pressure<rel_pressure -> neg_flag=1 - ; rel_pressure<=max_pressure -> neg_flag=0 + ; max_pressure < rel_pressure -> neg_flag=1 + ; rel_pressure <= max_pressure -> neg_flag=0 btfss neg_flag return - ; max_pressure<rel_pressure + ; max_pressure < rel_pressure movff sub_b+0,max_pressure+0 movff sub_b+1,max_pressure+1 - bsf FLAG_TFT_max_depth ; Set flag + bsf FLAG_TFT_max_depth ; set flag return set_min_temp: @@ -1150,8 +1221,8 @@ movff minimum_temperature+1,sub_a+1 SAFE_2BYTE_COPY temperature,sub_b call sub16 ; sub_c = sub_a - sub_b - ; minimum_temperature<T -> neg_flag=1 - ; T<=minimum_temperature -> neg_flag=0 + ; minimum_temperature < T -> neg_flag=1 + ; T <= minimum_temperature -> neg_flag=0 btfsc neg_flag return ; minimum_temperature >= T @@ -1161,8 +1232,8 @@ global set_dive_modes set_dive_modes: - btfsc high_altitude_mode ; In high altitude (Fly) mode? - bra set_dive_modes3 ; Yes! + btfsc high_altitude_mode ; in high altitude (fly) mode? + bra set_dive_modes3 ; YES set_dive_modes0: movlw LOW start_dive_threshold @@ -1177,23 +1248,22 @@ btfss neg_flag bra set_dive_modes2 ; too shallow (rel_pressure < dive_threshold) - btfsc realdive ; Dive longer than one minute? - clrf timeout_counter1+0 ; Yes, reset timeout counter +++ - - bsf divemode ; (Re-)Set divemode flag + btfsc realdive ; dive longer than one minute? + clrf timeout_counter1+0 ; YES - reset timeout counter + + bsf divemode ; (re-)set divemode flag bsf divemode2 ; displayed divetime is running return set_dive_modes2: - bcf divemode2 ; Stop time + bcf divemode2 ; stop time btfss realdive ; dive longer then one minute? - bcf divemode ; no -> this was no real dive - return ; No, return - - -set_dive_modes3: ; High-altitude mode + bcf divemode ; NO - this was no real dive + return ; YES - return + +set_dive_modes3: ; high-altitude mode btfsc realdive ; dive longer then one minute? - bra set_dive_modes0 ; Yes -> this is a real dive -> Use start_dive_threshold or ascend + bra set_dive_modes0 ; YES - this is a real dive -> Use start_dive_threshold or ascend movlw LOW high_altitude_dive_threshold movwf sub_a+0 @@ -1206,181 +1276,181 @@ cpfslt batt_percent return - movlw d'7' ; Type of Alarm (Battery Low) - movwf AlarmType ; Copy to Alarm Register + movlw d'7' ; type of alarm (battery Low) + movwf AlarmType ; copy to alarm register bsf event_occured ; set event flag movlw .0 - movff WREG,opt_brightness ; Set Brightness to ECO + movff WREG,opt_brightness ; set brightness to ECO return ; return + +reset_average: + bcf reset_average_depth ; clear reset-average flag + clrf average_depth_hold+0 ; clear the depth accumulator + clrf average_depth_hold+1 ; ... + clrf average_depth_hold+2 ; ... + clrf average_depth_hold+3 ; ... + clrf average_divesecs+0 ; clear the time accumulator + clrf average_divesecs+1 ; ... + SAFE_2BYTE_COPY rel_pressure,avg_rel_pressure ; prime result with current rel.pressure/depth + return + + calc_average_depth: - btfsc reset_average_depth ; Reset the Average depth? - rcall reset_average1 ; Reset the resettable average depth - - ; 1. Add new 2xdepth to the Sum of depths registers - SAFE_2BYTE_COPY rel_pressure,xB ; Buffer... + ; 1. compute rel_pressure x 2, because this routine is called every 2nd second only + SAFE_2BYTE_COPY rel_pressure,xB ; copy current rel pressure to xB bcf STATUS,C - rlcf xB+0,F - rlcf xB+1,F ; x2 - - movf xB+0,w + rlcf xB+0,F ; multiply rel pressure x 2 (via shift left) + rlcf xB+1,F ; ... + + ; 2a add (rel_pressure x 2) to the resettable depth accumulator + movf xB+0,W addwf average_depth_hold+0,F - movf xB+1,w + movf xB+1,W addwfc average_depth_hold+1,F - movlw d'0' + movlw .0 addwfc average_depth_hold+2,F - addwfc average_depth_hold+3,F ; Will work up to 9999mbar*60*60*24=863913600mbar - - ; Do the same for the _total registers (Non-Resettable) - movf xB+0,w + addwfc average_depth_hold+3,F ; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth) + + ; 2b add (rel_pressure x 2) to the total depth accumulator + movf xB+0,W addwf average_depth_hold_total+0,F - movf xB+1,w + movf xB+1,W addwfc average_depth_hold_total+1,F - movlw d'0' + movlw .0 addwfc average_depth_hold_total+2,F - addwfc average_depth_hold_total+3,F; Will work up to 9999mbar*60*60*24=863913600mbar - - ; 2. Compute Average Depth on base of average_divesecs:2 - movff average_divesecs+0,xB+0 - movff average_divesecs+1,xB+1 ; Copy + addwfc average_depth_hold_total+3,F ; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth) + + ; 3a compute avg_rel_pressure on base of average_divesecs:2 movff average_depth_hold+0,xC+0 movff average_depth_hold+1,xC+1 movff average_depth_hold+2,xC+2 - movff average_depth_hold+3,xC+3 - - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff average_depth_hold+3,xC+3 ; copy accumulated depth + movff average_divesecs+0,xB+0 + movff average_divesecs+1,xB+1 ; copy accumulated time + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder movff xC+0,avg_rel_pressure+0 - movff xC+1,avg_rel_pressure+1 - - btfss divemode2 ; displayed divetime is running? - return ; No (e.g. too shallow) - - ; 3. Compute Total Average Depth on base of total_divetime_seconds:2 - movff total_divetime_seconds+0,xB+0 - movff total_divetime_seconds+1,xB+1 ; Copy + movff xC+1,avg_rel_pressure+1 ; store result + + btfss divemode2 ; displayed divetime is running? + return ; NO (e.g. too shallow) + + ; 3b compute avg_rel_pressure_total on base of average_divesecs_total:2 movff average_depth_hold_total+0,xC+0 movff average_depth_hold_total+1,xC+1 movff average_depth_hold_total+2,xC+2 - movff average_depth_hold_total+3,xC+3 - call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff average_depth_hold_total+3,xC+3 ; copy accumulated depth + movff average_divesecs_total+0,xB+0 + movff average_divesecs_total+1,xB+1 ; copy accumulated time + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder movff xC+0,avg_rel_pressure_total+0 - movff xC+1,avg_rel_pressure_total+1 + movff xC+1,avg_rel_pressure_total+1 ; store result + + btfsc reset_average_depth ; reset the resettable average depth? + rcall reset_average ; YES - reset the resettable average depth + + TSTOSS opt_2ndDepthDisp ; drawing avg depth instead of max depth? + return ; NO - done + bsf FLAG_TFT_max_depth ; YES - flag to update display return -reset_average1: - clrf average_depth_hold+0 - clrf average_depth_hold+1 - clrf average_depth_hold+2 - clrf average_depth_hold+3 ; Clear average depth register - movlw d'2' - movwf average_divesecs+0 - clrf average_divesecs+1 - bcf reset_average_depth ; Clear flag - return - -test_switches_divemode: ; checks switches in divemode - btfsc divemode_menu ; Divemode menu shown? - bra test_switches_divemode_menu ; Yes, use menu processor - btfsc switch_left - ;bra test_switches_divemode2 ; Enter button pressed, check if we need to do something - goto menuview_toggle ; Menu or Simulator tasks; and return... - btfss switch_right - return ; No button press - tstfsz menupos2 ; any option shown? - bra test_switches_divemode1 ; Yes, do option tasks - bsf toggle_customview ; No, toggle custom view - return + +test_switches_divemode: ; checks switches in divemode + btfsc divemode_menu ; divemode menu shown? + bra test_switches_divemode_menu ; YES - use menu processor + btfsc switch_left ; NO - left button pressed? + goto menuview_toggle ; YES - menu or simulator tasks; and return... + btfss switch_right ; NO - right button pressed? + return ; NO - done + tstfsz menupos2 ; YES - any option shown? + bra test_switches_divemode1 ; YES - do option tasks + bsf toggle_customview ; NO - toggle custom view + return ; - done test_switches_divemode_menu: btfsc switch_left - bra test_switches_divemode_menu2; Move cursor - btfsc switch_right - bra test_switches_divemode_menu3; Enter submenu or do something - return ; No button press + bra test_switches_divemode_menu2 ; move cursor + btfsc switch_right ; left button pressed? + bra test_switches_divemode_menu3 ; YES - enter submenu or do something + return ; NO - done test_switches_divemode_menu1: clrf menupos1 test_switches_divemode_menu2: incf menupos1,F - incf menupos4,W ; menupos4+1 -> WREG - cpfslt menupos1 ; > menupos4 (Set in menu_processor.asm)? - bra test_switches_divemode_menu1; > Yes, set to 1 - call TFT_divemode_menu_cursor ; Update the cursor + incf menupos4,W ; menupos4 + 1 -> WREG + cpfslt menupos1 ; > menupos4 (set in menu_processor.asm)? + bra test_switches_divemode_menu1 ; YES - set to 1 + call TFT_divemode_menu_cursor ; update the cursor bcf switch_left - movlw divemode_menu_timeout ; Reload timeout - movwf timeout_counter2 ; timeout for divemode menu + movlw divemode_menu_timeout ; reload timeout + movwf timeout_counter2 ; timeout for divemode menu return -test_switches_divemode_menu3: ; Enter submenu or do something +test_switches_divemode_menu3: ; enter submenu or do something bcf switch_right ; decf menupos1,F ; menu_processor needs 0-5... - goto do_line_menu ; Warning! Trashes STKPTR and returns to diveloop_loop4: + goto do_line_menu ; Warning! trashes STKPTR and returns to diveloop_loop4: test_switches_divemode1: bcf switch_right movlw divemode_menuview_timeout - movwf timeout_counter2 ; Reload timeout + movwf timeout_counter2 ; reload timeout movff menupos2,WREG ; menupos2 holds number of customview/divemode menu function dcfsnz WREG,F - bra divemode_option_gaschange ; Switch to the indicated "better gas" + bra divemode_option_gaschange ; switch to the the "better gas" / "better diluent" dcfsnz WREG,F - bra divemode_option0 ; Start/Setup Divemode menu + bra divemode_option0 ; start/setup Divemode menu dcfsnz WREG,F - bra divemode_option1 ; Quit Simulation? + bra divemode_option1 ; quit simulation? dcfsnz WREG,F - bra divemode_option2 ; Descent 1m + bra divemode_option2 ; descent 1m dcfsnz WREG,F - bra divemode_option3 ; Ascend 1m + bra divemode_option3 ; ascend 1m dcfsnz WREG,F - bra divemode_option4 ; Quit Apnoe mode + bra divemode_option4 ; quit Apnoe mode dcfsnz WREG,F - bra divemode_option5 ; Reset Stopwatch (In Gauge mode) + bra divemode_option5 ; reset stopwatch (gauge mode only) dcfsnz WREG,F bra divemode_option6 ; +5mins simulation dcfsnz WREG,F - bra divemode_option7 ; Store heading + bra divemode_option7 ; store heading dcfsnz WREG,F - bra divemode_option8 ; Switch to alt. layout + bra divemode_option8 ; switch to alternative layout return gas_switched_common: - bcf divemode_gaschange ; Clear flag + bcf divemode_gaschange ; clear flag btfss FLAG_back_to_loop ; check if it is a switchback from OC bailout to loop bra gas_switched_common0 ; NO - continue with checking if selected gas is valid bcf FLAG_back_to_loop ; YES - clear flag - movff active_diluent,menupos1 ; reload last diluent + movff active_dil,menupos1 ; reload last diluent bra gas_switched_common1 ; continue with common part gas_switched_common0: - tstfsz menupos1 ; menupos1=0? + tstfsz menupos1 ; menupos1 = 0 ? bra gas_switched_common1 ; NO - valid gas return ; YES - something went wrong, invalid gas, abort gas_switched_common1: movf menupos1,W ; get selected gas into WREG (1-6) - - btfsc FLAG_ccr_mode ; in CCR mode? - bra gas_switched_common2 ; YES - configure diluent or bailout - btfsc FLAG_pscr_mode ; in pSCR mode? - bra gas_switched_common2 ; YES - configure diluent or bailout - - ; OC - rcall setup_gas_registers ; With WREG = Gas 1-6 - rcall deco_setup_oc_gases ; With WREG = Gas 1-6 + btfsc FLAG_oc_mode ; in OC mode? + bra gas_switched_common_OC ; YES + btfsc FLAG_bailout_mode ; in bailout? + bra gas_switched_common_OC ; YES +gas_switched_common_loop: ; NO to both - must be loop mode then + rcall setup_dil_registers ; with WREG = diluent 1-6 + rcall deco_setup_cc_diluents ; with WREG = diluent 1-6 bra gas_switched_common3 - - ; loop or bailout -gas_switched_common2: - rcall setup_dil_registers ; With WREG = diluent 1-6, in case of is_bailout reverts to OC gases - rcall deco_setup_cc_diluents ; With WREG = diluent 1-6, in case of is_bailout reverts to OC gases - +gas_switched_common_OC: + rcall setup_gas_registers ; with WREG = Gas 1-6 + rcall deco_setup_oc_gases ; with WREG = Gas 1-6 gas_switched_common3: - bsf FLAG_TFT_active_gas_divemode ; Redraw gas/setpoint/diluent + bsf FLAG_TFT_active_gas_divemode ; redraw gas/setpoint/diluent call restart_deco_engine_wo_ceiling ; abort any running deco calculations and restart the deco engine - - ; Set flags for profile recording + ; set flags for profile recording bsf event_occured ; set event flag - btfsc is_bailout ; Choose OC Bailouts (OC Gases) - bsf bailoutgas_event ; Bailout gas change - btfss is_bailout ; Choose OC Bailouts (OC Gases) + btfsc FLAG_bailout_mode ; choose OC Bailouts (OC Gases) + bsf bailoutgas_event ; bailout gas change + btfss FLAG_bailout_mode ; choose OC Bailouts (OC Gases) bsf stored_gas_changed ; OC gas change return @@ -1388,165 +1458,130 @@ ; Code to pass all parameters to the C code global get_first_gas_to_WREG -get_first_gas_to_WREG: ; Gets first gas (1-5) into WREG - lfsr FSR1,opt_gas_type ; Point to gas types - clrf lo ; start with Gas0 +get_first_gas_to_WREG: ; gets first gas (1-5) into WREG + lfsr FSR1,opt_gas_type ; point to gas types + clrf lo ; start with gas 0 get_first_gas_to_WREG2: movf lo,W - movf PLUSW1,W ; Get Type of Gas #lo + movf PLUSW1,W ; get type of gas #lo sublw .1 ; it is = 1 (First Gas) - bz get_first_gas_to_WREG3 ; Found the first gas! + bz get_first_gas_to_WREG3 ; found the first gas! incf lo,F ; ++ movlw NUM_GAS+1 - cpfseq lo ; All done? - bra get_first_gas_to_WREG2 ; Not yet - ; No first gas found, use #1 + cpfseq lo ; all done? + bra get_first_gas_to_WREG2 ; NO - not yet + ; no first gas found, use #1 movlw .0 - movff WREG,opt_gas_type+0 ; Set Gas1 to First + movff WREG,opt_gas_type+0 ; set gas 1 to First incf WREG,W ; 0 -> 1 return get_first_gas_to_WREG3: - movf lo,W ; Put into Wreg + movf lo,W ; put into WREG incf WREG,W ; 0-4 -> 1-5 - return ; Done + return ; done global get_first_dil_to_WREG -get_first_dil_to_WREG: ; Gets first dil (1-5) into WREG - lfsr FSR1,opt_dil_type ; Point to dil types - clrf lo ; start with Gas0 +get_first_dil_to_WREG: ; gets first dil (1-5) into WREG + lfsr FSR1,opt_dil_type ; point to dil types + clrf lo ; start with dil 0 get_first_dil_to_WREG2: movf lo,W - movf PLUSW1,W ; Get Type of Dil #lo + movf PLUSW1,W ; get type of Dil #lo sublw .1 ; it is = 1 (First Dil) - bz get_first_dil_to_WREG3 ; Found the first dil! + bz get_first_dil_to_WREG3 ; found the first dil! incf lo,F ; ++ movlw NUM_GAS+1 - cpfseq lo ; All done? - bra get_first_dil_to_WREG2 ; Not yet - ; No first dil found, use #1 + cpfseq lo ; all done? + bra get_first_dil_to_WREG2 ; NO - not yet + ; no first dil found, use #1 movlw .0 - movff WREG,opt_dil_type+0 ; Set Dil1 to First + movff WREG,opt_dil_type+0 ; set dil 1 to First incf WREG,W ; 0 -> 1 return get_first_dil_to_WREG3: - movf lo,W ; Put into Wreg + movf lo,W ; Put into WREG incf WREG,W ; 0-4 -> 1-5 - return ; Done - - global deco_setup_oc_gases + return ; done + + deco_setup_oc_gases: ; with currently breathed gas in WREG (1-5 or 6) - movff WREG,char_I_current_gas ; gas to start with when doing the deco calculations - - banksel opt_gas_type ; opt_gas_type[] and opt_OC_bail_gas_change[] are together in bank common2 - - movff opt_gas_He_ratio+0,char_I_deco_He_ratio+0 - movff opt_gas_O2_ratio+0,char_I_deco_O2_ratio+0 - - movlw .3 ; 3=Deco - cpfseq opt_gas_type+0 ; Gas is deco type? - clrf opt_OC_bail_gas_change+0 ; No, clear depth for 0=Disabled, 1=First and 2=Travel - - movff opt_gas_He_ratio+1,char_I_deco_He_ratio+1 - movff opt_gas_O2_ratio+1,char_I_deco_O2_ratio+1 - movlw .3 ; 3=Deco - cpfseq opt_gas_type+1 ; Gas is deco type? - clrf opt_OC_bail_gas_change+1 ; No, clear depth for 0=Disabled, 1=First and 2=Travel - - movff opt_gas_He_ratio+2,char_I_deco_He_ratio+2 - movff opt_gas_O2_ratio+2,char_I_deco_O2_ratio+2 - movlw .3 ; 3=Deco - cpfseq opt_gas_type+2 ; Gas is deco type? - clrf opt_OC_bail_gas_change+2 ; No, clear depth for 0=Disabled, 1=First and 2=Travel - - movff opt_gas_He_ratio+3,char_I_deco_He_ratio+3 - movff opt_gas_O2_ratio+3,char_I_deco_O2_ratio+3 - movlw .3 ; 3=Deco - cpfseq opt_gas_type+3 ; Gas is deco type? - clrf opt_OC_bail_gas_change+3 ; No, clear depth for 0=Disabled, 1=First and 2=Travel - - movff opt_gas_He_ratio+4,char_I_deco_He_ratio+4 - movff opt_gas_O2_ratio+4,char_I_deco_O2_ratio+4 - movlw .3 ; 3=Deco - cpfseq opt_gas_type+4 ; Gas is deco type? - clrf opt_OC_bail_gas_change+4 ; No, clear depth for 0=Disabled, 1=First and 2=Travel - - banksel common - - ; Setup char_I_deco_gas_change array - movff opt_OC_bail_gas_change+0, char_I_deco_gas_change+0 - movff opt_OC_bail_gas_change+1, char_I_deco_gas_change+1 - movff opt_OC_bail_gas_change+2, char_I_deco_gas_change+2 - movff opt_OC_bail_gas_change+3, char_I_deco_gas_change+3 - movff opt_OC_bail_gas_change+4, char_I_deco_gas_change+4 - - ; switch to oc mode movff char_O_deco_status,lo ; working copy of char_O_deco_status in bank common +deco_setup_oc_gases_pre: ; entry point with lo preloaded + movff WREG,char_I_current_gas ; set gas to start with when doing the deco calculations + ; + ; Memory Map: + ; --------------------------------------------------------------------------------- + ; opt_gas_O2_ratio res NUM_GAS | char_I_deco_O2_ratio res NUM_GAS + ; opt_dil_O2_ratio res NUM_GAS | + ; opt_gas_He_ratio res NUM_GAS | char_I_deco_He_ratio res NUM_GAS + ; opt_dil_He_ratio res NUM_GAS | + ; opt_gas_type res NUM_GAS | char_I_deco_gas_type res NUM_GAS + ; opt_dil_type res NUM_GAS | + ; opt_gas_change res NUM_GAS | char_I_deco_gas_change res NUM_GAS + ; opt_dil_change res NUM_GAS | + ; + lfsr FSR2,char_I_deco_O2_ratio ; Load FSR2 with base address of char_I_deco_O2_ratio. + ; FSR2 will step through all char_I_deco_... vars. + lfsr FSR1,opt_gas_O2_ratio ; load FSR1 with base address of opt_gas_O2_ratio + rcall deco_setup_copy ; copy all OC O2 ratios + lfsr FSR1,opt_gas_He_ratio ; load FSR1 with base address of opt_gas_He_ratio + rcall deco_setup_copy ; copy all OC He ratios + lfsr FSR1,opt_gas_type ; load FSR1 with base address of opt_gas_type + rcall deco_setup_copy ; copy all gas types + lfsr FSR1,opt_gas_change ; load FSR1 with base address of opt_gas_change + rcall deco_setup_copy ; copy all gas change depths + ; switch to oc mode bcf lo,DECO_MODE_PSCR_FLAG ; clear the pSCR-mode flag (may not be set, but never mind) bcf lo,DECO_MODE_LOOP_FLAG ; clear the loop/CCR-mode flag movff lo,char_O_deco_status ; bank safe write-back of char_O_deco_status - return - global deco_setup_cc_diluents -deco_setup_cc_diluents: ; with currently breathed gas in WREG (1-5 or 6) - btfsc is_bailout ; check if in bailout condition - bra deco_setup_oc_gases ; revert to setting up OC gases in bailout condition - - movff WREG,char_I_current_gas ; gas to start with when doing the deco calculations - - movff opt_dil_He_ratio+0,char_I_deco_He_ratio+0 - movff opt_dil_O2_ratio+0,char_I_deco_O2_ratio+0 - movff opt_dil_type+0,WREG ; 0=Disabled, 1=First, 2=Normal - tstfsz WREG ; Disabled? - bra $+4 ; No - movff WREG,char_I_dil_change+0 ; Yes, clear char_I_deco_gas_change (Bank safe) - - movff opt_dil_He_ratio+1,char_I_deco_He_ratio+1 - movff opt_dil_O2_ratio+1,char_I_deco_O2_ratio+1 - movff opt_dil_type+1,WREG ; 0=Disabled, 1=First, 2=Normal - tstfsz WREG ; Disabled? - bra $+4 ; No - movff WREG,char_I_dil_change+1 ; Yes, clear char_I_dil_change - - movff opt_dil_He_ratio+2,char_I_deco_He_ratio+2 - movff opt_dil_O2_ratio+2,char_I_deco_O2_ratio+2 - movff opt_dil_type+2,WREG ; 0=Disabled, 1=First, 2=Normal - tstfsz WREG ; Disabled? - bra $+4 ; No - movff WREG,char_I_dil_change+2 ; Yes, clear char_I_dil_change - - movff opt_dil_He_ratio+3,char_I_deco_He_ratio+3 - movff opt_dil_O2_ratio+3,char_I_deco_O2_ratio+3 - movff opt_dil_type+3,WREG ; 0=Disabled, 1=First, 2=Normal - tstfsz WREG ; Disabled? - bra $+4 ; No - movff WREG,char_I_dil_change+3 ; Yes, clear char_I_dil_change - - movff opt_dil_He_ratio+4,char_I_deco_He_ratio+4 - movff opt_dil_O2_ratio+4,char_I_deco_O2_ratio+4 - movff opt_dil_type+4,WREG ; 0=Disabled, 1=First, 2=Normal - tstfsz WREG ; Disabled? - bra $+4 ; No - movff WREG,char_I_dil_change+4 ; Yes, clear char_I_dil_change - - ; Setup char_I_deco_gas_change array - movff char_I_dil_change+0, char_I_deco_gas_change+0 - movff char_I_dil_change+1, char_I_deco_gas_change+1 - movff char_I_dil_change+2, char_I_deco_gas_change+2 - movff char_I_dil_change+3, char_I_deco_gas_change+3 - movff char_I_dil_change+4, char_I_deco_gas_change+4 - - ; switch to CCR / pSCR mode +deco_setup_cc_diluents: ; with currently breathed diluent in WREG (1-5 or 6) movff char_O_deco_status,lo ; working copy of char_O_deco_status in bank common +deco_setup_cc_diluents_pre: ; entry point with lo preloaded + btfsc FLAG_bailout_mode ; check if in bailout condition | --------------- FOR SAFETY ONLY -------------- + bra deco_setup_oc_gases_pre ; YES - revert to setting up OC gases | This branch should never happen to be taken... + movff WREG,char_I_current_gas ; NO - set diluent to start with when doing the deco calculations + ; + ; Memory Map: + ; --------------------------------------------------------------------------------- + ; opt_gas_O2_ratio res NUM_GAS | + ; opt_dil_O2_ratio res NUM_GAS | char_I_deco_O2_ratio res NUM_GAS + ; opt_gas_He_ratio res NUM_GAS | + ; opt_dil_He_ratio res NUM_GAS | char_I_deco_He_ratio res NUM_GAS + ; opt_gas_type res NUM_GAS | + ; opt_dil_type res NUM_GAS | char_I_deco_gas_type res NUM_GAS + ; opt_gas_change res NUM_GAS | + ; opt_dil_change res NUM_GAS | char_I_deco_gas_change res NUM_GAS + ; + lfsr FSR2,char_I_deco_O2_ratio ; Load FSR2 with base address of char_I_deco_O2_ratio. + ; FSR2 will step through all char_I_deco_... vars. + lfsr FSR1,opt_dil_O2_ratio ; load FSR1 with base address of opt_dil_O2_ratio + rcall deco_setup_copy ; copy all dil O2 ratios + lfsr FSR1,opt_dil_He_ratio ; load FSR1 with base address of opt_dil_He_ratio + rcall deco_setup_copy ; copy all dil He ratios + lfsr FSR1,opt_dil_type ; load FSR1 with base address of opt_dil_type + rcall deco_setup_copy ; copy all dil types + lfsr FSR1,opt_dil_change ; load FSR1 with base address of opt_dil_change + rcall deco_setup_copy ; copy all dil change depths + ; switch to CCR / pSCR mode bsf lo,DECO_MODE_LOOP_FLAG ; loop flag is set in both, CCR and pSCR mode bcf lo,DECO_MODE_PSCR_FLAG ; clear pSCR mode flag by default btfsc FLAG_pscr_mode ; check if we are in pSCR mode bsf lo,DECO_MODE_PSCR_FLAG ; YES - set additional flag for pSCR mode - movff lo,char_O_deco_status ; bank safe write-back of char_O_deco_status - + movff lo,char_O_deco_status ; bank safe write-back of char_O_deco_status return +deco_setup_copy: + movlw NUM_GAS ; load loop counter with number of gases (5) +deco_setup_copy_loop: + movff POSTINC1,POSTINC2 ; copy from (FSR1) to (FSR2) + decfsz WREG ; decrement loop counter and check if it became 0 + bra deco_setup_copy_loop ; NO - not yet, loop + return ; YES - done + + global setup_gas_registers setup_gas_registers: ; with currently breathed gas in WREG (1-5 or 6) movwf active_gas ; set as current gas @@ -1554,76 +1589,92 @@ cpfseq active_gas ; gas = gas6 ? bra setup_gas_registers_15 ; NO - load gas 1-5 movff gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine - movff gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine + movff gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine + movlw .3 ; declare gas6 as a deco gas + movff WREG,char_I_current_gas_type; copy gas type to deco engine + movff curr_depth,char_I_gas6_depth; set current depth as change depth bra setup_gas_registers_com ; continue with common part setup_gas_registers_15: decf active_gas,W ; 1-5 -> 0-4 - lfsr FSR1,opt_gas_O2_ratio+0 + lfsr FSR1,opt_gas_O2_ratio movff PLUSW1,char_I_O2_ratio ; copy gas 1-5 O2 ratio to deco engine - lfsr FSR1,opt_gas_He_ratio+0 + lfsr FSR1,opt_gas_He_ratio movff PLUSW1,char_I_He_ratio ; copy gas 1-5 He ratio to deco engine -setup_gas_registers_com: - ;lfsr FSR1,opt_gas_type ; commented out - currently not used anywhere - ;movff PLUSW1,active_gas_type ; 0=Disabled, 1=First, 2=Travel, 3=Deco + lfsr FSR1,opt_gas_type ; + movff PLUSW1,char_I_current_gas_type ; copy gas 1-5 type (0=Disabled, 1=First, 2=Travel, 3=Deco) +setup_gas_registers_com: movff char_O_main_status,lo ; working copy of char_O_main_status in bank common bcf lo,DECO_MODE_PSCR_FLAG ; clear the pSCR-mode flag (may not be set, but never mind) bcf lo,DECO_MODE_LOOP_FLAG ; clear the loop/CCR-mode flag movff lo,char_O_main_status ; bank safe write-back of char_O_main_status - movf active_gas,W ; reload WREG with diluent 1-5 or 6 (important!) + movf active_gas,W ; reload WREG with gas 1-5 or 6 (important!) return global setup_dil_registers setup_dil_registers: ; with currently breathed gas in WREG (1-5 or 6) - btfsc is_bailout ; check if in bailout condition - bra setup_gas_registers ; revert to setting up OC gases in bailout condition - movwf active_gas ; set as current gas - movff WREG,active_diluent ; remember for when switching back from bailout to loop + btfsc FLAG_bailout_mode ; check if in bailout condition | --------------- FOR SAFETY ONLY -------------- + bra setup_gas_registers ; revert to setting up OC gases in bailout condition | This branch should never happen to be taken... + movwf active_dil ; set as current diluent movlw .6 - cpfseq active_gas ; diluent = gas6 ? + cpfseq active_dil ; diluent = gas6 ? bra setup_dil_registers_15 ; NO - load diluent 1-5 movff gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine movff gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine + movlw .2 ; declare gas6 as a normal diluent + movff WREG,char_I_current_gas_type; copy gas type to deco engine + movff curr_depth,char_I_gas6_depth; set current depth as change depth bra setup_dil_registers_com ; continue with common part setup_dil_registers_15: - decf active_gas,W ; 1-5 -> 0-4 - lfsr FSR1,opt_dil_O2_ratio+0 + decf active_dil,W ; 1-5 -> 0-4 + lfsr FSR1,opt_dil_O2_ratio movff PLUSW1,char_I_O2_ratio ; copy diluent 1-5 O2 ratio to deco engine - lfsr FSR1,opt_dil_He_ratio+0 + lfsr FSR1,opt_dil_He_ratio movff PLUSW1,char_I_He_ratio ; copy diluent 1-5 He ratio to deco engine + lfsr FSR1,opt_dil_type ; + movff PLUSW1,char_I_current_gas_type ; copy dil type (0=Disabled, 1=First, 2=Normal) setup_dil_registers_com: - ;lfsr FSR1,opt_dil_type ; commented out - currently not used anywhere - ;movff PLUSW1,active_gas_type ; 0=Disabled, 1=First, 2=Normal (there is no type 3 for diluents) movff char_O_main_status,lo ; working copy of char_O_main_status in bank common bsf lo,DECO_MODE_LOOP_FLAG ; loop flag is set in both, CCR and pSCR mode bcf lo,DECO_MODE_PSCR_FLAG ; clear pSCR mode flag by default btfsc FLAG_pscr_mode ; check if we are in pSCR mode bsf lo,DECO_MODE_PSCR_FLAG ; YES - set additional flag for pSCR mode movff lo,char_O_main_status ; bank safe write-back of char_O_main_status - movf active_gas,W ; reload WREG with diluent 1-5 or 6 (important!) + movf active_dil,W ; reload WREG with diluent 1-5 or 6 (important!) return -divemode_option_gaschange: ; Switch to the better gas - movff better_gas_number,menupos1 ; 1-5 - bsf divemode_gaschange ; Change the gas in the dive mode loop... - call menuview_toggle_reset ; Reset to zero (Zero=no menuview) - bcf better_gas_available ; Clear flag immediately + +divemode_option_gaschange: ; switch to the "better gas" / "better diluent" + btfsc FLAG_oc_mode ; in OC mode? + bra divemode_option_gaschange_oc; YES + btfsc FLAG_bailout_mode ; in bailout? + bra divemode_option_gaschange_oc; YES +divemode_option_gaschange_loop: ; in CCR/pSCR mode and not in bailout + movff best_dil_number,menupos1 ; NO - select best diluent + bcf better_dil_available ; - clear flag immediately + bra divemode_option_gaschange3 ; - continue with common part +divemode_option_gaschange_oc: ; in OC or bailout + movff best_gas_number,menupos1 ; select best gas + bcf better_gas_available ; clear flag immediately +divemode_option_gaschange3 ; common part + bsf divemode_gaschange ; command a gas/diluent change + call menuview_toggle_reset ; terminate the options menu return -divemode_option0: ; Start/Setup Divemode menu - call TFT_clear_divemode_menu ; Clear menu area +divemode_option0: ; start/setup dive mode menu + call TFT_clear_divemode_menu ; clear menu area bcf menuview call do_main_divemenu global divemode_option0_return divemode_option0_return: ; movlw .1 -; movwf menupos1 ; Set to first option in divemode menu - call TFT_divemode_menu_cursor ; Show the cursor +; movwf menupos1 ; set to first option in dive mode menu + call TFT_divemode_menu_cursor ; show the cursor movlw divemode_menu_timeout - movwf timeout_counter2 ; timeout for divemode menu - bsf divemode_menu ; Set flag - clrf menupos2 ; Clear option counter - goto diveloop_loop4 ; Goto back to diveloop (menu processor trashes STKPTR!) + movwf timeout_counter2 ; timeout for dive mode menu + bsf divemode_menu ; set flag + clrf menupos2 ; clear option counter + goto diveloop_loop4 ; go back to dive loop (menu processor trashes STKPTR!) divemode_option4: movlw d'58' ; two seconds left @@ -1631,18 +1682,20 @@ movlw apnoe_timeout-1 ; apnoe timeout [min] movwf apnoe_timeout_counter btfss simulatormode_active ; in simulator mode? - return ; No -divemode_option1: ; Quit simulation mode + return ; NO + ;bra divemode_option1 ; YES + +divemode_option1: ; quit simulation mode banksel isr_backup movlw LOW .1000 movwf sim_pressure+0 movlw HIGH .1000 - movwf sim_pressure+1 ; Set to 0m -> End of Dive + movwf sim_pressure+1 ; set to 0m -> end of dive banksel common - call menuview_toggle_reset ; Reset to zero (Zero=no menuview) - - btfss FLAG_apnoe_mode ; In Apnoe mode? - return ; No + call menuview_toggle_reset ; reset to zero (zero = no menu view) + + btfss FLAG_apnoe_mode ; in apnoe mode? + return ; NO - done movlw d'58' ; two seconds left movwf timeout_counter1+0 movlw apnoe_timeout-1 ; apnoe timeout [min] @@ -1662,51 +1715,74 @@ divemode_option2: ; plus 1m banksel isr_backup movlw d'100' - addwf sim_pressure+0 + addwf sim_pressure+0,F movlw .0 - addwfc sim_pressure+1 + addwfc sim_pressure+1,F rcall divemode_simulator_check_limits banksel common return divemode_option5: - call menuview_toggle_reset ; Reset to zero (Zero=no menuview) - bsf reset_average_depth ; Set Flag + call menuview_toggle_reset ; reset to zero (zero = no menu view) + bsf reset_average_depth ; set flag return divemode_option6: - bcf divemode2 ; Stop divetime + ; advance tissues and deco by 5 minutes + movlw .5 ; + 5 minutes + movff WREG,char_I_sim_advance_time; copy to mailbox + call restart_deco_engine + + ; stop divetime incrementing in ISR + bcf divemode2 + + ; add 5 minutes to divemins movlw .5 addwf divemins+0,F movlw .0 - addwfc divemins+1,F ; Add 5 mins + addwfc divemins+1,F + + ; add 5 minutes (5 * 60 seconds) to total_divetime_seconds + movlw LOW (.5*.60) + addwf total_divetime_seconds+0,F + movlw HIGH (.5*.60) + addwfc total_divetime_seconds+1,F + + ; continue dive time incrementing in ISR + bsf divemode2 + + ; add 5 minutes (5 * 60 seconds) to resettable time accumulator movlw LOW (.5*.60) addwf average_divesecs+0,F movlw HIGH (.5*.60) - addwfc average_divesecs+1,F ; Add 5*60 seconds + addwfc average_divesecs+1,F + + ; add 5 minutes (5 * 60 seconds) to total time accumulator movlw LOW (.5*.60) - addwf total_divetime_seconds+0,F + addwf average_divesecs_total+0,F movlw HIGH (.5*.60) - addwfc total_divetime_seconds+1,F ; Add 5*60 seconds - - ; 1. Add 300xdepth to the sum of depths registers - SAFE_2BYTE_COPY rel_pressure, xB ; Buffer... + addwfc average_divesecs_total+1,F + + + ; calculate 300 x depth in mbar (300 = 5 min * 60 sec/min) + SAFE_2BYTE_COPY rel_pressure, xB movlw LOW (.5*.60) movwf xA+0 movlw HIGH (.5*.60) movwf xA+1 call mult16x16 ; xA*xB=xC - movf xC+0,w + ; add to the resettable depth accumulator + movf xC+0,W addwf average_depth_hold+0,F - movf xC+1,w + movf xC+1,W addwfc average_depth_hold+1,F - movf xC+2,w + movf xC+2,W addwfc average_depth_hold+2,F - movf xC+3,w - addwfc average_depth_hold+3,F ; Will work up to 9999mbar*60*60*24=863913600mbar - - ; Do the same for the _total registers (Non-Resettable) + movf xC+3,W + addwfc average_depth_hold+3,F + + ; add to the total depth accumulator movf xC+0,w addwf average_depth_hold_total+0,F movf xC+1,w @@ -1714,12 +1790,14 @@ movf xC+2,w addwfc average_depth_hold_total+2,F movf xC+3,w - addwfc average_depth_hold_total+3,F; Will work up to 9999mbar*60*60*24=863913600mbar - - movlw .5 ; + 5 minutes - movff WREG,char_I_sim_advance_time; copy to mailbox - bsf divemode2 ; continue divetime - call restart_deco_engine + addwfc average_depth_hold_total+3,F + + IFDEF _cave_mode + ; update backtracking data + movlw .5 ; add backtrack data for 5 minutes + call update_backtrack ; make it so + ENDIF + goto menuview_toggle_reset ; and return... divemode_option7: @@ -1727,38 +1805,42 @@ movff compass_heading_shown+0,compass_bearing+0 movff compass_heading_shown+1,compass_bearing+1 bsf compass_bearing_set ; set flag - goto menuview_toggle_reset ; Done and return... - + goto menuview_toggle_reset ; and return... + divemode_option8: - bsf alternative_divelayout ; Set flag for mode - bsf FLAG_TFT_divemode_mask_alt ; Set flag for mask - movlw .1 - movwf menupos3 ; For the customviews... - call TFT_ClearScreen ; Clear screen - goto menuview_toggle_reset ; Done and return... + bsf alternative_divelayout ; set flag for alternative layout mode + call menuview_toggle_reset ; terminate the pre-menu + call TFT_ClearScreen ; clear the whole screen + bsf FLAG_TFT_divemode_mask_alt ; set flag to draw the alternative mask + movff menupos3,customview_divemode; back-up the custom view shown in normal layout + clrf menupos3 ; select the default alternative layout + call customview_mask_alternative ; draw the default alternative layout + return ; done + divemode_simulator_check_limits: - ; Check limits (150m and 0m) - movlw LOW d'16000' ; Compare to 16bar=16000mbar (150m). + ; check limits (150m and 0m) + movlw LOW d'16000' ; compare to 16 bar = 16000 mbar (150m) subwf sim_pressure+0,W movlw HIGH d'16000' subwfb sim_pressure+1,W - bnc divemode_simulator_check_limits2 ; No-carry = borrow = not deeper - - ; Too deep, limit to 150m + bnc divemode_simulator_check_limits2 ; no carry = borrow = not deeper + + ; too deep, limit to 150m movlw LOW d'16000' movwf sim_pressure+0 movlw HIGH d'16000' movwf sim_pressure+1 return + divemode_simulator_check_limits2: - movlw LOW d'1000' ; Compare to 1bar == 0m == 1000 mbar. + movlw LOW d'1000' ; compare to 1 bar == 0m == 1000 mbar subwf sim_pressure+0,W movlw HIGH d'1000' subwfb sim_pressure+1,W - btfsc STATUS,C ; No-carry = borrow = not deeper. - return ; Deeper than 0m == Ok. - ; Too shallow, limit to 0m + btfsc STATUS,C ; no carry = borrow = not deeper + return ; deeper than 0 m == ok + ; too shallow, limit to 0m movlw LOW d'1000' movwf sim_pressure+0 movlw HIGH d'1000' @@ -1766,291 +1848,383 @@ return ;============================================================================= -; Compare all enabled gas in list, to see if a better one is available. +; Find the best gas and diluent for the current depth +; and check if a gas/diluent change is to be advised. +; +; Output: best_gas_number : number of best gas, 0= none avail, 255= not computed +; best_dil_number : number of best dil, 0= none avail, 255= not computed +; better_gas_available : flag indicating if a change is advised +; better_dil_available : flag indicating if a change is advised +; +; +; in CCR and pSCR mode: - checks both, gases and diluents for respective best gas / best diluent +; - if not in bailout, sets better_dil_available on diluents +; - if in bailout, sets better_gas_available on OC gases +; +; in OC mode : - checks only gases for best gas +; - sets better_gas_available on OC gases ; -; Output: better_gas_available, better_gas_number +check_gas_best: + movff amb_press_10+0,xA+0 ; copy ambient pressure / 10 into xA:2, will be used by ppO2 min/max checks later + movff amb_press_10+1,xA+1 ; ... + ; set maximum ppO2 allowed + movff char_I_ppO2_max,ppO2_max ; max ppO2 for working phase (default) + movff char_O_deco_info,lo ; bank-safe copy of deco info vector + btfsc lo,deco_flag ; is the ppo2 deco limit enabled? + movff char_I_ppO2_max_deco,ppO2_max ; YES - replace by max ppO2 for deco phase + ; check dive mode + btfsc FLAG_oc_mode ; in OC mode? + bra check_gas_best_gas ; YES - skip diluents, check for best gas only + +check_gas_best_dil: + ; set minimum ppO2 required + movff char_I_ppO2_min,WREG ; min ppO2 for pure diluent in CCR mode (default) + btfsc FLAG_pscr_mode ; in pSCR mode? + movff char_I_ppO2_min_loop,ppO2_min ; YES - replace by min ppO2 for pure diluent in pSCR mode + ; preset results to nothing found + clrf best_gas_num ; initialize best diluent as 0 = nothing found yet + bcf better_dil_available ; =1: a better diluent is available and a gas change is advised in divemode +; ; current diluent = 'gas6' ? +; movlw .6 ; +; cpfseq active_dil ; using 'gas6' as current diluent? +; bra check_gas_best_dil0 ; NO - continue +; bra check_gas_best_dil3 ; YES - suppress better diluent search in this case +;check_gas_best_dil0: + ; check all diluents + lfsr FSR1,opt_dil_O2_ratio ; set base address for diluent arrays + movff active_dil,lo ; number of currently used diluent + setf best_gas_depth ; initialize change depth of best dil found so far to 255 meter +; original code + clrf check_gas_num + incf check_gas_num,F + rcall check_gas_best_common ; check diluent 1 + incf check_gas_num,F + rcall check_gas_best_common ; check diluent 2 + incf check_gas_num,F + rcall check_gas_best_common ; check diluent 3 + incf check_gas_num,F + rcall check_gas_best_common ; check diluent 4 + incf check_gas_num,F + rcall check_gas_best_common ; check diluent 5 +; alternative code +; movlw .5 +; movwf check_gas_num +;check_gas_best_dil_loop: +; rcall check_gas_best_common +; decfsz check_gas_num +; bra check_gas_best_dil_loop ; -check_gas_change: ; Checks if a better gas should be selected (by user) - bcf better_gas_available ; =1: A better gas is available and a gas change is advised in divemode - clrf WREG - movff WREG,better_gas_number ; clear better gas register - - SAFE_2BYTE_COPY rel_pressure,xA - movlw d'100' - movwf xB+0 - clrf xB+1 - call div16x16 ; compute depth in full m -> result in xC+0 - - btfsc FLAG_pscr_mode ; in PSCR mode? - bra check_gas_change2 ; YES - check for diluents - btfss FLAG_ccr_mode ; in CCR mode? - bra check_gas_change_OC_bail ; NO - check for OC -check_gas_change2: - btfsc is_bailout ; in bailout? - bra check_gas_change_OC_bail ; YES - check for OC - - ; Check Diluents - movlw .0 - rcall check_dil_common ; With Gas 0-4 in WREG - movlw .1 - rcall check_dil_common ; With Gas 0-4 in WREG - movlw .2 - rcall check_dil_common ; With Gas 0-4 in WREG - movlw .3 - rcall check_dil_common ; With Gas 0-4 in WREG - movlw .4 - rcall check_dil_common ; With Gas 0-4 in WREG - bra check_gas_change_exit - -check_gas_change_OC_bail: - movlw .0 - rcall check_gas_common ; With Gas 0-4 in WREG - movlw .1 - rcall check_gas_common ; With Gas 0-4 in WREG - movlw .2 - rcall check_gas_common ; With Gas 0-4 in WREG - movlw .3 - rcall check_gas_common ; With Gas 0-4 in WREG - movlw .4 - rcall check_gas_common ; With Gas 0-4 in WREG - ;bra check_gas_change_exit - -check_gas_change_exit: - bsf FLAG_TFT_active_gas_divemode; redraw gas/setpoint/diluent - btfss better_gas_available ; is a better gas available? - bcf blinking_better_gas ; NO - clear blinking flag - btfsc better_gas_available ; is a better gas available? - return ; YES - clrf WREG ; NO - clear better_gas_number (for gaslist display) - movff WREG,better_gas_number + ; store result + movff best_gas_num,best_dil_number ; store new best diluent found (1-5 or 0 of no usable diluent available) + ; check if change advices shall be given in general + btfsc FLAG_bailout_mode ; in bailout? + bra check_gas_best_gas ; YES - no better diluent advice when in bailout +check_gas_best_dil1: + ; check if a change advice shall be given right now + movf best_dil_number,W ; load number of best diluent into WREG (1-5) + bz check_gas_best_dil3 ; has a best diluent been found at all? NO - nothing to signal for + cpfseq active_dil ; is this the currently used diluent? + bra check_gas_best_dil2 ; NO + bra check_gas_best_dil3 ; YES - no need to signal a better diluent if this diluent is already in use +check_gas_best_dil2: + btfsc setpoint_fallback ; is a fallback warning active? + bra check_gas_best_dil3 ; YES - suppress better diluent prompt in this case + ; not using the best gas - show better diluent hint whenever a better diluent is available + bsf better_dil_available ; signal that a better diluent is available + bsf FLAG_TFT_active_gas_divemode ; redraw gas/setpoint/diluent +check_gas_best_dil3: + btfss better_dil_available ; shall a better diluent be signaled for? + bcf blinking_better_dil ; NO - clear blinking flag + ; continue with checking for best bailout gas + +check_gas_best_gas: + ; set minimum ppO2 required + movff char_I_ppO2_min,ppO2_min ; min ppO2 for OC/Bailout + ; preset results to nothing found + clrf best_gas_num ; initialize best gas as 0 = nothing found yet + bcf better_gas_available ; =1: a better gas is available and a gas change is advised in divemode +; ; current gas = 'gas6' ? +; movlw .6 ; +; cpfseq active_gas ; using 'gas6' as current gas? +; bra check_gas_best_gas0 ; NO - continue +; bra check_gas_best_gas3 ; YES - suppress better gas search in this case +;check_gas_best_gas0: + ; check all gases + lfsr FSR1,opt_gas_O2_ratio ; set base address for gas arrays + movff active_gas,lo ; number of currently used gas + setf best_gas_depth ; initialize change depth of best gas found so far to 255 meter +; original code + clrf check_gas_num + incf check_gas_num,F + rcall check_gas_best_common ; check gas 1 + incf check_gas_num,F + rcall check_gas_best_common ; check gas 2 + incf check_gas_num,F + rcall check_gas_best_common ; check gas 3 + incf check_gas_num,F + rcall check_gas_best_common ; check gas 4 + incf check_gas_num,F + rcall check_gas_best_common ; check gas 5 +; alternative code +; movlw .5 +; movwf check_gas_num +;check_gas_best_gas_loop: +; rcall check_gas_best_common +; decfsz check_gas_num +; bra check_gas_best_gas_loop +; + ; store result + movff best_gas_num,best_gas_number ; store new best gas found (1-5 or 0 of no usable gas available) + ; check if change advices shall be given in general + btfsc FLAG_oc_mode ; in OC mode? + bra check_gas_best_gas1 ; YES + btfsc FLAG_bailout_mode ; in bailout? + bra check_gas_best_gas1 ; YES + return ; NO - no better (OC) gas advice when not in OC or bailout mode +check_gas_best_gas1: ; check if we are already on the best gas + ; check if a change advice shall be given right now + movf best_gas_number,W ; load number of best gas into WREG (1-5) + bz check_gas_best_gas3 ; has a best gas been found at all? NO - nothing to signal for + cpfseq active_gas ; is this the currently used gas? + bra check_gas_best_gas2 ; NO + bra check_gas_best_gas3 ; YES - no need to signal a better gas if this gas is already in use +check_gas_best_gas2: + ; not using the best gas - show better gas hint whenever a better gas is available + bsf better_gas_available ; YES - signal that a better gas is available + bsf FLAG_TFT_active_gas_divemode ; YES - redraw gas/setpoint/diluent +check_gas_best_gas3: + btfss better_gas_available ; shall a better gas be signaled for? + bcf blinking_better_gas ; NO - clear blinking flag return -check_gas_common: ; With Gas 0-4 in WREG - btfsc better_gas_available ; Better Gas already found? - return ; Yes, return - lfsr FSR1,opt_gas_type ; 0=Disabled, 1=First, 2=Travel, 3=Deco - btfss PLUSW1,0 ; Test for Bit0 and 1 -> type=3 -> Deco - return ; No - btfss PLUSW1,1 ; Test for Bit0 and 1 -> type=3 -> Deco - return ; No - incf WREG,W ; 1-5 - cpfseq active_gas ; is this gas current gas? - bra check_gas_common2 ; No - return ; Yes, skip test for active gas -check_gas_common2: - decf WREG,W ; 0-4 - movwf hi ; Save tested gas 0-4 - lfsr FSR1,opt_OC_bail_gas_change - movff PLUSW1,lo ; Change depth into lo - movlw minimum_change_depth - cpfsgt lo ; Change depth>minimum_change_depth? - return ; No, Change depth not deep enough, skip! - movf xC+0,W ; load depth in m into WREG - cpfsgt lo ; gas_change_depth < current depth? - bra check_gas_common3 ; No, check if we are within the better_gas_window_pos window - incf hi,W ; 1-5 - movff WREG,better_gas_number ; number (1-5) of the "better gas" in divemode, =0: no better gas available - movlw better_gas_window_neg - subwf lo,W ; Change depth-better_gas_window_neg - cpfslt xC+0 ; current depth<Change depth-better_gas_window_neg? - bra check_gas_common4 ; Ok, now check the better gas ppO2<char_I_ppO2_max - return -check_gas_common3: - incf hi,W ; 1-5 - movff WREG,better_gas_number ; number (1-5) of the "better gas" in divemode, =0: no better gas available - movlw better_gas_window_pos - addwf lo,W ; Change depth+better_gas_window_pos - cpfsgt xC+0 ; current depth>Change depth+better_gas_window_pos? - bra check_gas_common4 ; Ok, now check the better gas ppO2<char_I_ppO2_max - return -check_gas_common4: - movf hi,W ; gas 0-4 into WREG - lfsr FSR1,char_I_deco_O2_ratio ; load base address char_I_deco_O2_ratio array - movff PLUSW1,lo ; read O2 ratio from array into lo - - SAFE_2BYTE_COPY amb_pressure, xA - movlw d'10' - movwf xB+0 +check_gas_best_common: ; with gas to be checked in check_gas_num (1-5) +; ; and current gas in lo (1-5) + ; + ; Memory Map: + ; --------------------------------------------------------------------------------------- + ; opt_gas_O2_ratio res 5 ; base address for gases + ; opt_dil_O2_ratio res 5 ; base address for diluents + ; opt_gas_He_ratio res 5 ; (not needed here) + ; opt_dil_He_ratio res 5 ; (not needed here) + ; opt_gas_type res 5 ; has offset of 20 bytes from base address for gases + ; opt_dil_type res 5 ; has offset of 20 bytes from base address for diluents + ; opt_gas_change res 5 ; has offset of 10 bytes from opt_gas_type + ; opt_dil_change res 5 ; has offset of 10 bytes from opt_dil_type + + ; get gas data + decf check_gas_num,W ; (1-5) -> (0-4) into WREG to be used as index + movff PLUSW1,check_gas_O2_ratio ; load O2 ratio (%) of current gas/dil into check_gas_O2_ratio + addlw .20 ; add offset of 20 bytes to index type in opt_gas_type/opt_dil_type + movff PLUSW1,check_gas_type ; load type of current gas/dil into check_gas_type (0=disabled, 1=first, 2=travel/normal, 3=deco/-) + addlw .10 ; add offset of 10 bytes to index change depth in opt_gas_change/opt_dil_change + movff PLUSW1,check_gas_depth ; load change depth of current gas/dil into check_gas_depth + ; check if gas is usable (i.e. not disabled) + tstfsz check_gas_type ; type = disabled (0)? + bra check_gas_best_common0 ; NO - continue checks + movf check_gas_num,W ; YES - get the number of the gas to be checked (1-5) + cpfseq lo ; - is this the currently used gas? + return ; NO - skip disabled gases which are not the current gas + bra check_gas_best_common1 ; YES - a gas in use overrides it's disabled status, therefore treat it as available +check_gas_best_common0: + ; skip deco gases (type=3) if not in deco mode, but search among all enabled gases when in loop or bailout mode + movlw .3 + cpfseq check_gas_type ; type = deco (3)? + bra check_gas_best_common1 ; NO - proceed + btfsc FLAG_bailout_mode ; YES - in bailout? + bra check_gas_best_common1 ; YES - proceed, include deco gases + movff char_O_main_status,WREG ; NO - get main deco mode + btfsc WREG,DECO_MODE_LOOP_FLAG ; - in loop mode? + bra check_gas_best_common1 ; YES - proceed, include deco gases + movff char_O_deco_info,WREG ; NO - get deco info vector + btfss WREG,deco_flag ; - in deco mode (deco_flag set), i.e. use of deco gases allowed? + return ; NO - skip deco gas while not in deco mode +check_gas_best_common1: ; YES - proceed +; ; check if gas change depth is below minimum change depth +; movlw minimum_change_depth ; for value see definition in hwos.inc +; cpfsgt check_gas_depth ; change depth of checked gas > minimum_change_depth? +; return ; NO - change depth not deep enough, skip and check next gas + ; check if gas is usable, i.e. its change depth is below or equal to the current depth + movf curr_depth,W ; load current depth (in m) into WREG + cpfslt check_gas_depth ; change depth of checked gas < (shallower than) current depth? + bra check_gas_best_common2 ; NO - gas is usable + return ; YES - gas is not usable +check_gas_best_common2: + ; check if this gas is the first best gas candidate + movf best_gas_num,W ; get best gas found so far (1-5) or 0 if none found yet + tstfsz WREG ; has a best gas candidate been found yet? + bra check_gas_best_common3 ; YES - check if the new one is better than the one we have so far + bra check_gas_best_common4 ; NO - no need to do the above mentioned check +check_gas_best_common3: + ; check if the change depth of the checked gas is < (shallower) than the change depth of the best gas found so far + movf best_gas_depth,W ; load change depth of best gas so far into WREG + cpfslt check_gas_depth ; change depth of checked gas < (shallower than) change depth of best gas so far? + return ; NO - this gas is not better than the best already found +check_gas_best_common4: + ; check if the gas fits into the ppO2 limits + movff check_gas_O2_ratio,xB+0 ; xB = O2 ratio, xA is still loaded with (p_amb / 10) clrf xB+1 - call div16x16 ; xC=p_amb/10 - movff xC+0,xA+0 - movff xC+1,xA+1 - movff lo,xB+0 ; =O2 ratio - clrf xB+1 - call mult16x16 ; lo * p_amb/10 - - ; Check very high ppO2 manually - tstfsz xC+2 ; char_I_O2_ratio * p_amb/10 > 65536, ppO2>6,55bar? - return ; Done. - ; Check if ppO2>3,30bar - btfsc xC+1,7 - return ; Done. - - ; Check for low ppo2 - movff xC+0,sub_b+0 - movff xC+1,sub_b+1 - movff char_I_ppO2_min,WREG - mullw d'100' ; char_I_ppO2_min*100 - movff PRODL,sub_a+0 - movff PRODH,sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag - return ; Done (Too low). - - ;check if we are within our warning thresholds! + call mult16x16 ; xC = O2 ratio * (p_amb / 10) + ; check for very high ppO2 + tstfsz xC+2 ; O2_ratio * p_amb / 10 > 65536, i.e. ppO2 > 6.55 bar ? + return ; YES - gas is not usable + btfsc xC+1,7 ; check if ppO2 > 3.30 bar + return ; YES - gas is not usable + ; check for low ppO2 movff xC+0,sub_a+0 movff xC+1,sub_a+1 - movff char_I_ppO2_max_deco,WREG ; ppO2 max for MOD calculation and color coding in divemode - addlw .1 ; e.g. >1.60 - mullw d'100' ; char_I_ppO2_max*100 + movf ppO2_min,W + mullw .100 ; char_I_ppO2_min * 100 movff PRODL,sub_b+0 movff PRODH,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bsf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode - return ; Done. - - -check_dil_common: ; With Dil 0-4 in WREG - btfsc better_gas_available ; Better Diluent already found? - return ; Yes, return - lfsr FSR1,opt_dil_type ; 0=Disabled, 1=First, 2=Normal - tstfsz PLUSW1 ; =0? - bra check_dil_common1 ; No - return ; Yes, skip inactive diluents for test -check_dil_common1: - incf WREG,W ; 1-5 - cpfseq active_gas ; is this the current diluent? - bra check_dil_common2 ; No - return ; Yes, skip test for active diluent -check_dil_common2: - decf WREG,W ; 0-4 - movwf hi ; Save tested diluent 0-4 - lfsr FSR1,char_I_dil_change - movff PLUSW1,lo ; Change depth into lo - movlw minimum_change_depth - cpfsgt lo ; Change depth>minimum_change_depth? - return ; No, Change depth not deep enough, skip! - movf xC+0,W ; load depth in m into WREG - cpfsgt lo ; gas_change_depth < current depth? - return ; No, check next gas - incf hi,W ; 1-5 - movff WREG,better_gas_number ; number (1-5) of the "better gas" in divemode, =0: no better gas available - movlw better_gas_window_neg - subwf lo,W ; Change depth-better_gas_window_neg - cpfslt xC+0 ; current depth<Change depth-better_gas_window_neg? - bsf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; within limit? + return ; NO - too low, gas is not usable + ; check for high ppO2 + movf ppO2_max,W + mullw .100 ; ppO2_max * 100 + movff PRODL,sub_b+0 + movff PRODH,sub_b+1 + infsnz sub_b+0,F ; add 1 mbar to allowance to avoid exclusion on equal + incf sub_b+1,F + call subU16 ; sub_c = sub_a - sub_b + btfss neg_flag ; within limit? + return ; NO - too high, gas is not usable + ; we have a (new) best gas + movff check_gas_num, best_gas_num ; set checked gas (1-5) as best gas + movff check_gas_depth,best_gas_depth ; memorize its change depth return ;============================================================================= ; Check for Auto-SP ; -check_dive_autosp: ; Check for Auto-SP +check_dive_autosp: ; check for Auto-SP movff opt_ccr_mode,WREG ; =0: Fixed SP, =1: Sensor, =2: Auto SP sublw .2 ; opt_ccr_mode = 2 (Auto SP)? - bz check_dive_autosp2 ; Yes, check - return ; No, return for Sensor or Fixed mode + bz check_dive_autosp2 ; YES - check + return ; NO - return for sensor or fixed mode check_dive_autosp2: - SAFE_2BYTE_COPY rel_pressure,xA - movlw d'100' - movwf xB+0 - clrf xB+1 - call div16x16 ; compute depth in full m -> result in xC+0 ; Check SP2 - btfsc sp2_switched ; =1: This setpoint has been autoselected already - bra check_dive_autosp3 ; Skip check - movff char_I_setpoint_change+1,lo ; Get depth in m - tstfsz lo ; =0? - bra check_dive_autosp2a ; No, continue - bra check_dive_autosp3 ; Skip check + btfsc sp2_switched ; SP 2 used so far? + bra check_dive_autosp3 ; YES - continue with SP 3 + movff char_I_setpoint_change+1,lo ; NO - get depth in m + tstfsz lo ; - SP change depth = 0 ? + bra check_dive_autosp2a ; NO - continue + bra check_dive_autosp3 ; YES - continue with SP 3 check_dive_autosp2a: - decf lo,W ; -1 -> WREG - cpfsgt xC+0 ; Compare with depth - bra check_dive_autosp3 ; lower depth, do not switch + decf lo,W ; SP change depth -1 -> WREG + cpfsgt curr_depth ; current depth > change depth - 1 ? + bra check_dive_autosp3 ; NO - continue with SP 3 ; auto switch to SP2 - movff char_I_setpoint_cbar+1,char_I_const_ppO2 ; Use SetPoint - rcall xmit_sp_set_flag - bsf sp2_switched ; Set flag + movff char_I_setpoint_cbar+1,char_I_const_ppO2 ; YES - use SP + rcall xmit_sp_set_flag ; - send SP to external devices + bsf sp2_switched ; - set SP 2 used flag check_dive_autosp3: ; Check SP3 - btfsc sp3_switched ;=1: This setpoint has been autoselected already - bra check_dive_autosp4 ; Skip check - movff char_I_setpoint_change+2,lo ; Get depth in m - tstfsz lo ; =0? - bra check_dive_autosp3a ; No, continue - bra check_dive_autosp4 ; Skip check + btfsc sp3_switched ; SP 3 used so far? + bra check_dive_autosp4 ; YES - continue with SP 4 + movff char_I_setpoint_change+2,lo ; NO - get depth in m + tstfsz lo ; - SP change depth = 0 ? + bra check_dive_autosp3a ; NO - continue + bra check_dive_autosp4 ; YES - continue with SP 4 check_dive_autosp3a: - decf lo,W ; -1 -> WREG - cpfsgt xC+0 ; Compare with depth - bra check_dive_autosp4 ; lower depth, do not switch + decf lo,W ; SP change depth -1 -> WREG + cpfsgt curr_depth ; current depth > change depth - 1 ? + bra check_dive_autosp4 ; NO - continue with SP 4 ; auto switch to SP3 - movff char_I_setpoint_cbar+2,char_I_const_ppO2 ; Use SetPoint - rcall xmit_sp_set_flag - bsf sp3_switched ; Set flag + movff char_I_setpoint_cbar+2,char_I_const_ppO2 ; YES - use SP + rcall xmit_sp_set_flag ; - send SP to external devices + bsf sp3_switched ; - set SP 3 used flag check_dive_autosp4: ; Check SP4 - btfsc sp4_switched ;=1: This setpoint has been autoselected already - bra check_dive_autosp5 ; Skip check - movff char_I_setpoint_change+3,lo ; Get depth in m - tstfsz lo ; =0? - bra check_dive_autosp4a ; No, continue - bra check_dive_autosp5 ; Skip check + btfsc sp4_switched ; SP 4 used so far? + bra check_dive_autosp5 ; YES - continue with SP 5 + movff char_I_setpoint_change+3,lo ; NO - get depth in m + tstfsz lo ; - SP change depth = 0 ? + bra check_dive_autosp4a ; NO - continue + bra check_dive_autosp5 ; YES - continue with SP 5 check_dive_autosp4a: - decf lo,W ; -1 -> WREG - cpfsgt xC+0 ; Compare with depth - bra check_dive_autosp5 ; lower depth, do not switch + decf lo,W ; SP change depth -1 -> WREG + cpfsgt curr_depth ; current depth > change depth - 1 ? + bra check_dive_autosp5 ; NO - continue with SP 5 ; auto switch to SP4 - movff char_I_setpoint_cbar+3,char_I_const_ppO2 ; Use SetPoint - rcall xmit_sp_set_flag - bsf sp4_switched ; Set flag + movff char_I_setpoint_cbar+3,char_I_const_ppO2 ; YES - use SP + rcall xmit_sp_set_flag ; - send SP to external devices + bsf sp4_switched ; - set SP 4 used flag check_dive_autosp5: ; Check SP5 - btfsc sp5_switched ;=1: This setpoint has been autoselected already - bra check_dive_autosp6 ; Skip check - movff char_I_setpoint_change+4,lo ; Get depth in m - tstfsz lo ; =0? - bra check_dive_autosp5a ; No, continue - bra check_dive_autosp6 ; Skip check + btfsc sp5_switched ; SP 5 used so far? + bra check_dive_autosp6 ; YES - done + movff char_I_setpoint_change+4,lo ; NO - get depth in m + tstfsz lo ; - SP change depth = 0 ? + bra check_dive_autosp5a ; NO - continue + bra check_dive_autosp6 ; YES - done check_dive_autosp5a: - decf lo,W ; -1 -> WREG - cpfsgt xC+0 ; Compare with depth - bra check_dive_autosp6 ; lower depth, do not switch + decf lo,W ; SP change depth -1 -> WREG + cpfsgt curr_depth ; current depth > change depth - 1 ? + bra check_dive_autosp6 ; NO - done ; auto switch to SP5 - movff char_I_setpoint_cbar+4,char_I_const_ppO2 ; Use SetPoint - rcall xmit_sp_set_flag - bsf sp5_switched ; Set flag + movff char_I_setpoint_cbar+4,char_I_const_ppO2 ; YES - use SP + rcall xmit_sp_set_flag ; - send SP to external devices + bsf sp5_switched ; - set SP 5 used flag check_dive_autosp6: return xmit_sp_set_flag: movff char_I_const_ppO2,WREG - call transmit_setpoint ; Transmit current setpoint from WREG (in cbar) to external electronics - bsf setpoint_changed ; Set flag (for profile) - bsf event_occured ; Set event flag + call transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics + bsf setpoint_changed ; set flag (for profile) + bsf event_occured ; set event flag return set_logbook_marker: bcf FLAG_set_marker ; clear flag - movlw d'6' ; set type of Alarm (manual marker) - movwf AlarmType ; copy to Alarm Register - bsf event_occured ; Set event flag + movlw d'6' ; set type of alarm (manual marker) + movwf AlarmType ; copy to alarm register + bsf event_occured ; set event flag return ;============================================================================= -; Setup everything to enter divemode. +; Setup everything to enter dive mode ; + global dive_boot_oc_bail +dive_boot_oc_bail: + ; copy opt_gas_types into backup (for "lost gas" feature) + movff opt_gas_type+0,opt_gas_type_backup+0 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+1,opt_gas_type_backup+1 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+2,opt_gas_type_backup+2 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+3,opt_gas_type_backup+3 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + movff opt_gas_type+4,opt_gas_type_backup+4 ; 0=Disabled, 1=First, 2=Travel, 3=Deco + ; done + return + + global dive_boot_oc dive_boot_oc: - rcall get_first_gas_to_WREG ; Gets first gas (1-5) into WREG + ; set-up registers + rcall get_first_gas_to_WREG ; get first gas (1-5) into WREG rcall setup_gas_registers ; set-up of gas parameters of currently breathed gas (with WREG = gas 1-5) rcall deco_setup_oc_gases ; set-up of gas list for deco calculations (with WREG = gas 1-5) return + global dive_boot_cc dive_boot_cc: - bcf is_bailout ; =1: Bailout - bcf setpoint_fallback ; =1: Fallback to SP1 due to external O2 sensor failure - bcf blinking_setpoint ; Reset blinking SP flag - + ; copy opt_dil_types into backup (for "lost diluent" feature) + movff opt_dil_type+0,opt_dil_type_backup+0 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+1,opt_dil_type_backup+1 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+2,opt_dil_type_backup+2 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+3,opt_dil_type_backup+3 ; 0=Disabled, 1=First, 2=Normal + movff opt_dil_type+4,opt_dil_type_backup+4 ; 0=Disabled, 1=First, 2=Normal + ; clear flags + bcf FLAG_bailout_mode ; =1: bailout + bcf setpoint_fallback ; =1: fallback to SP1 due to external O2 sensor failure + ; set-up registers + rcall get_first_dil_to_WREG ; get first diluent (1-5) into WREG + rcall setup_dil_registers ; set-up of diluent parameters for currently breathed diluent (with WREG = current diluent 1-5) + rcall deco_setup_cc_diluents ; set-up of diluent list for deco calculations (with WREG = current diluent 1-5) + ; done + return + +dive_boot_cc_part2: ; revoke sensors from usage if they do not have a valid calibration bsf use_O2_sensor1 bsf use_O2_sensor2 @@ -2061,108 +2235,120 @@ bcf use_O2_sensor2 btfss sensor3_calibrated_ok bcf use_O2_sensor3 - + ; check for external HUD/ppO2 Monitor btfss optical_input ; do we have an optical input? - bra dive_boot_cc_0 ; No - ; Copy (initial) valid flags from HUD/ppO2 Monitor + bra dive_boot_cc_part2_1 ; NO + ; copy (initial) valid flags from HUD/ppO2 Monitor btfsc sensor1_active - bsf use_O2_sensor1 - btfsc sensor2_active - bsf use_O2_sensor2 + bsf use_O2_sensor1 + btfsc sensor2_active + bsf use_O2_sensor2 btfsc sensor3_active - bsf use_O2_sensor3 - -dive_boot_cc_0: + bsf use_O2_sensor3 +dive_boot_cc_part2_1: ; In pSCR mode, only settings 0 (calculated ppO2) and 1 (ppO2 from sensors) are defined. - ; In case we still have 3 (auto SP) selected out of previous ccr mode, we reset to 0. + ; In case we still have 3 (auto SP) selected out of previous CCR mode, we reset to 0. btfss FLAG_pscr_mode - bra dive_boot_cc_1 + bra dive_boot_cc_part2_2 movff opt_ccr_mode,WREG ; =0: Fixed SP (CCR) / calculated SP (pSCR), =1: Sensor, =2: Auto SP sublw .2 ; opt_ccr_mode = 1 (Auto SP)? - bnz dive_boot_cc_1 + bnz dive_boot_cc_part2_2 movlw .0 movff WREG,opt_ccr_mode - -dive_boot_cc_1: +dive_boot_cc_part2_2: bsf setpoint_changed ; set flag (for profile) - bcf sp2_switched ; =1: This setpoint has been auto-selected already - bcf sp3_switched ; =1: This setpoint has been auto-selected already - bcf sp4_switched ; =1: This setpoint has been auto-selected already - bcf sp5_switched ; =1: This setpoint has been auto-selected already - - rcall get_first_dil_to_WREG ; get first gas (1-5) into WREG - rcall setup_dil_registers ; set-up of gas parameters for currently breathed gas (with WREG = current gas 1-5) - rcall deco_setup_cc_diluents ; set-up of gas list for deco calculations (with WREG = current gas 1-5) - + bcf sp2_switched ; =1: this setpoint has been auto-selected already + bcf sp3_switched ; =1: this setpoint has been auto-selected already + bcf sp4_switched ; =1: this setpoint has been auto-selected already + bcf sp5_switched ; =1: this setpoint has been auto-selected already ; Start with SP1 (CCR) or 0 (pSCR) as default. ; If in sensor mode, this value will be overwritten by calc_deko_divemode_sensor clrf WREG ; preload WREG with setpoint value 0 for pSCR calculated - btfss FLAG_ccr_mode ; are we in CCR mode? - bra dive_boot_cc_2 ; NO - keep preloaded value + btfsc FLAG_ccr_mode ; are we in CCR mode? movff char_I_setpoint_cbar+0,WREG ; YES - get value of setpoint 1 -dive_boot_cc_2: movff WREG,char_I_const_ppO2 ; write setpoint to deco engine call transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics goto calc_deko_divemode_sensor ; read & process sensor data (and return) + diveloop_boot: + + ; do the basic initialization call restart_set_modes_and_flags - call I2C_sleep_accelerometer ; stop accelerometer - call I2C_sleep_compass ; stop compass + ; stop accelerometer and compass + call I2C_sleep_accelerometer + call I2C_sleep_compass + + ; reset max pressure aka max depth + clrf WREG + movff WREG,max_pressure+0 + movff WREG,max_pressure+1 + + ; initialize press needs to zero and invalid (not yet computed) state + clrf WREG ; set WREG to 0 + IFDEF _cave_mode + movff WREG,char_I_backtrack_time ; clear backtracking time (index to char_I_backtrack_depth) + movff WREG,char_I_backtrack_depth ; prime first entry with depth 0 + ENDIF + bsf WREG,int_is_zero ; set zero flag + bsf WREG,int_invalid_flag ; set invalid flag (additionally) + banksel int_O_ascent_pres_need ; select bank with shared output vars + movwf int_O_ascent_pres_need+1 ; Set flags for tank pressure needs = 0 before p2_deco.c + movwf int_O_ascent_pres_need+3 ; can do it. If this is not done here and the gas needs + movwf int_O_ascent_pres_need+5 ; custom view is shown before p2_deco.c completes the first + movwf int_O_ascent_pres_need+7 ; deco calculation, some rubbish numbers from last dive or + movwf int_O_ascent_pres_need+9 ; simulation may be shown + banksel common ; back to bank common + + ; configure the deco engine + clrf hi + bsf hi,DECO_Z_FACTOR_FLAG ; enable Z factor mode by default + TSTOSS opt_ZfactorUse ; shall use Z factor mode? + bcf hi,DECO_Z_FACTOR_FLAG ; NO - disable again + IFDEF _rx_functions + bsf hi,DECO_TR_FUNCTIONS ; enable TR mode by default + btfss FLAG_tr_enabled ; shall use TR mode? + bcf hi,DECO_TR_FUNCTIONS ; NO - disable again + ENDIF + movff hi,char_O_main_status ; bank-safe copy to deco engine + + movff char_O_deco_status,lo ; bank-safe read + bsf lo,DECO_STATUS_0_FLAG ; set init- | ATTENTION: The deco engine must be started in init state! If omitted, it may + bsf lo,DECO_STATUS_1_FLAG ; state, | enter an infinite loop at some point in time and brick the OSTC! + bcf lo,DECO_PLAN_FLAG ; normal plan mode, + bcf lo,DECO_VOLUME_FLAG ; disable gas volume calculation, and + bcf lo,DECO_ASCENT_FLAG ; disable delayed ascent calculation + movff lo,char_O_deco_status ; bank-safe copy back to deco engine clrf WREG - movff WREG,max_pressure+0 ; clear some variables - movff WREG,max_pressure+1 - - ; init in invalid data state - clrf WREG ; set WREG to 0 - bsf WREG,int_invalid_flag ; set invalid flag - bsf WREG,int_is_zero ; set zero flag - movff WREG,int_O_tank_pres_need+1 ; Set flags for tank pressure needs = 0 before p2_deco.c - movff WREG,int_O_tank_pres_need+3 ; can do it. If this is not done here and the gas needs - movff WREG,int_O_tank_pres_need+5 ; custom view is shown before p2_deco.c completes the first - movff WREG,int_O_tank_pres_need+7 ; deco calculation, some rubbish numbers from last dive of - movff WREG,int_O_tank_pres_need+9 ; simulation may be shown - - ; configure the deco engine: - movff char_O_deco_status,WREG ; bank-safe copy - bsf WREG,DECO_STATUS_0_FLAG ; configure init ... - bsf WREG,DECO_STATUS_1_FLAG ; ... state, - bcf WREG,DECO_PLAN_FLAG ; normal plan mode, - bsf WREG,DECO_CNS_FLAG ; enable CNS calculation (CNS at end of dive), - bcf WREG,DECO_VOLUME_FLAG ; disable gas volume calculation, and - bcf WREG,DECO_ASCENT_FLAG ; disable delayed ascent calculation - movff WREG,char_O_deco_status ; bank-safe copy back - - clrf WREG - movff WREG,char_O_main_status ; reset char_O_main_status - - movlw deco_distance - movff WREG,char_I_deco_distance - movff opt_last_stop,char_I_depth_last_deco - movff opt_GF_low,char_I_GF_Low_percentage - movff opt_GF_high,char_I_GF_High_percentage - - bcf use_agf ; Start with normal GF set - bcf divemode_menu ; clear divemode menu flag - - bcf alternative_divelayout ; Start with default layout - + movff WREG,char_O_deco_warnings ; clear any deco warnings remaining from last dive + movff WREG,char_O_deco_info ; clear any deco infos remaining from last dive + + movlw deco_distance ; load distance between actual depth and depth used for deco calculation + movff WREG,char_I_deco_distance ; write distance to the deco engine + + movff opt_last_stop,char_I_depth_last_deco ; write last stop depth to deco engine + movff opt_GF_low,char_I_GF_Low_percentage ; write GF low to deco engine + movff opt_GF_high,char_I_GF_High_percentage ; write GF high to deco engine + + bcf onesectoggle ; clear toggle bit for calculation phasing + bcf use_agf ; start with normal GF set + bcf divemode_menu ; clear dive mode menu flag + bcf alternative_divelayout ; start with default layout bcf blinking_depth_prev ; clear flag for blinking depth - bcf blinking_depth_warning ; clear flag for blinking depth bcf blinking_depth_toggle ; clear flag for blinking depth + bcf blinking_depth_warning ; clear flag for blinking depth as warning + bcf blinking_depth_attention ; clear flag for blinking depth as attention + bcf max_depth_greater_100m ; clear flag for last max/avg depth was > 100 m movlw d'1' movwf apnoe_max_pressure+0 clrf apnoe_max_pressure+1 ; clrf apnoe_surface_mins ; clrf apnoe_surface_secs - clrf apnoe_mins - clrf divemins+0 - clrf divemins+1 - - ; Copy date and time for logbook + + ; copy date and time for logbook movff year,start_year movff month,start_month movff day,start_day @@ -2171,146 +2357,187 @@ movff int_O_CNS_fraction+0,CNS_start+0 ; save CNS value at beginning of dive movff int_O_CNS_fraction+1,WREG ; get high byte to WREG - bcf WREG,int_warning_flag ; clear warning flag - bcf WREG,int_attention_flag ; clear attention flag + bcf WREG,int_warning_flag ; clear warning flag + bcf WREG,int_attention_flag ; clear attention flag movff WREG,CNS_start+1 ; move high byte on movff int_O_gradient_factor+0,GF_start ; save GF value at beginning of dive (only lower byte used for value) - bcf no_more_divesecs ; =1: do no longer show seconds in divemode + bcf no_more_divesecs ; =1: do no longer show seconds in dive mode bcf divemode_menu_active clrf menupos1 - clrf menupos2 ; Reset to zero (Zero=no premenu or simulator task) - bsf sensors_agree ; init of sensors disagree warning system - - btfsc FLAG_ccr_mode - bra diveloop_boot_cc - btfsc FLAG_pscr_mode - bra diveloop_boot_cc - rcall dive_boot_oc - bra diveloop_boot_cont - -diveloop_boot_cc: - rcall dive_boot_cc - -diveloop_boot_cont: - ; Copy opt_dil_types into backup (For "lost gas" feature) - movff opt_dil_type+0,opt_dil_type_backup+0 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+1,opt_dil_type_backup+1 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+2,opt_dil_type_backup+2 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+3,opt_dil_type_backup+3 ; 0=Disabled, 1=First, 2=Normal - movff opt_dil_type+4,opt_dil_type_backup+4 ; 0=Disabled, 1=First, 2=Normal - ; Copy opt_gas_types into backup (For "lost gas" feature) - movff opt_gas_type+0,opt_gas_type_backup+0 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+1,opt_gas_type_backup+1 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+2,opt_gas_type_backup+2 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+3,opt_gas_type_backup+3 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - movff opt_gas_type+4,opt_gas_type_backup+4 ; 0=Disabled, 1=First, 2=Travel, 3=Deco - ; Also copy change depths into backup (For "lost gas" feature) - movff char_I_dil_change+0,opt_dil_change_backup+0 ; Gas change depths Diluents - movff char_I_dil_change+1,opt_dil_change_backup+1 ; Gas change depths Diluents - movff char_I_dil_change+2,opt_dil_change_backup+2 ; Gas change depths Diluents - movff char_I_dil_change+3,opt_dil_change_backup+3 ; Gas change depths Diluents - movff char_I_dil_change+4,opt_dil_change_backup+4 ; Gas change depths Diluents - ; Also copy change depths into backup (For "lost gas" feature) - movff opt_OC_bail_gas_change+0,opt_OC_bail_gas_change_backup+0; Gas change depths OC/Bailout - movff opt_OC_bail_gas_change+1,opt_OC_bail_gas_change_backup+1; Gas change depths OC/Bailout - movff opt_OC_bail_gas_change+2,opt_OC_bail_gas_change_backup+2; Gas change depths OC/Bailout - movff opt_OC_bail_gas_change+3,opt_OC_bail_gas_change_backup+3; Gas change depths OC/Bailout - movff opt_OC_bail_gas_change+4,opt_OC_bail_gas_change_backup+4; Gas change depths OC/Bailout - - clrf WREG - movff WREG,better_gas_number ; clear better gas register - - bcf show_safety_stop ; =1: Show the safety stop - clrf safety_stop_countdown ; Clear count-down - - clrf samplesecs + clrf menupos2 ; reset to zero (Zero=no pre-menu or simulator task) + bsf sensors_agree ; init of sensors disagree warning system + + bcf show_safety_stop ; =1: show the safety stop + clrf safety_stop_countdown ; clear count-down + + clrf samplesecs ; timer for data logging clrf apnoe_timeout_counter ; timeout in minutes clrf timeout_counter1+0 ; takes care of the timeout (low byte) clrf timeout_counter1+1 ; takes care of the timeout (high byte) clrf AlarmType ; Clear all alarms bcf event_occured ; clear flag - clrf average_depth_hold_total+0 + clrf average_divesecs_total+0 ; clear non-resettable time accumulator + clrf average_divesecs_total+1 + clrf average_depth_hold_total+0 ; clear non-resettable average depth clrf average_depth_hold_total+1 clrf average_depth_hold_total+2 - clrf average_depth_hold_total+3 ; Clear Non-Resettable Average - rcall reset_average1 ; Reset the resettable average depth - bcf decostop_active - bcf better_gas_available ; =1: A better gas is available and a gas change is advised in divemode - call ghostwriter_short_header ; Write short header with divenumber into profile memory + clrf average_depth_hold_total+3 + call reset_average ; reset the resettable average depth + + IFDEF _rx_functions + btfss FLAG_tr_enabled ; TR functions enabled? + bra diveloop_boot_0 ; NO - skip TR function initialization + ; YES - initialize TR function variables + banksel int_O_sac_rate + clrf int_O_sac_rate+0 ; clear low byte of SAC rate + clrf int_O_pressure_need+0 ; clear low byte of 1st pressure need value + clrf int_O_pressure_need+2 ; clear low byte of 2nd pressure need value + banksel int_IO_pressure_value + clrf int_IO_pressure_value+0 ; clear low byte of 1st pressure reading value + clrf int_IO_pressure_value+2 ; clear low byte of 2nd pressure reading value + clrf int_I_pressure_drop+0 ; clear low byte of 1st pressure drop value + clrf int_I_pressure_drop+2 ; clear low byte of 2nd pressure drop value + clrf char_I_pressure_gas+0 ; clear gas selection of 1st pressure reading + clrf char_I_pressure_gas+1 ; clear gas selection of 2nd pressure reading + clrf char_I_pressure_age+0 ; clear age of 1st pressure reading + clrf char_I_pressure_age+1 ; clear age of 2nd pressure reading + clrf char_I_pressure_stat+0 ; clear status of 1st pressure reading + clrf char_I_pressure_stat+1 ; clear status of 2nd pressure reading + clrf WREG ; clear WREG + bsf WREG,int_not_avail_flag ; set WREG to coding for integer numbers -> data not available + banksel int_O_sac_rate + movwf int_O_sac_rate+1 ; copy to high byte of SAC rate + movwf int_O_pressure_need+1 ; copy to high byte of 1st pressure need value + movwf int_O_pressure_need+3 ; copy to high byte of 1st pressure need value + banksel int_IO_pressure_value + movwf int_IO_pressure_value+1 ; copy to high byte of 1st pressure reading value + movwf int_IO_pressure_value+3 ; copy to high byte of 2nd pressure reading value + movwf int_I_pressure_drop+1 ; copy to high byte of 1st pressure drop value + movwf int_I_pressure_drop+3 ; copy to high byte of 1st pressure drop value + banksel gas__last_1st ; select bank with vars for pressure drop calculation + setf gas__last_1st ; invalidate last gas of 1st reading + setf gas__last_2nd ; invalidate last gas of 2nd reading + banksel common ; back to bank common + ENDIF + +diveloop_boot_0: + bcf decostop_active ; clear flag for being in deco + setf best_gas_number ; initialize best gas as not computed yet (255) + setf best_dil_number ; initialize best diluent as not computed yet (255) + bcf better_gas_available ; =1: a better gas is available and a gas change is advised + bcf better_dil_available ; =1: a better diluent is available and a gas change is advised + + rcall dive_boot_oc_bail ; basic settings required for all modes + + btfsc FLAG_oc_mode ; in OC mode? + rcall dive_boot_oc ; YES - add OC mode settings + + btfsc FLAG_ccr_mode ; in CCR mode? + rcall dive_boot_cc ; YES - add CC mode settings + btfsc FLAG_ccr_mode ; in CCR mode? + rcall dive_boot_cc_part2 ; YES - add CC sensor and SP settings + + btfsc FLAG_pscr_mode ; in pSCR mode? + rcall dive_boot_cc ; YES - add CC mode settings + btfsc FLAG_pscr_mode ; in pSCR mode? + rcall dive_boot_cc_part2 ; YES - add CC sensor and SP settings + + call ghostwriter_short_header ; write short header with dive number into profile memory btfsc simulatormode_active bra diveloop_boot_1 - ; Normal mode = Surface pressure is the pressure 30mn before dive. - SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface ;copy surfacepressure to deco routine - SAFE_2BYTE_COPY last_surfpressure_30min, last_surfpressure ;copy surfacepressure to last_surfpressure for correct depth + + ; normal mode = surface pressure is the pressure 30 minutes before dive + SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface ;copy surface pressure to deco routine + SAFE_2BYTE_COPY last_surfpressure_30min, last_surfpressure ;copy surface pressure to last_surfpressure for correct depth bra diveloop_boot_2 diveloop_boot_1: - ; Simulator mode: Surface pressure is 1bar. - movlw LOW .1000 - movff WREG,int_I_pres_surface+0 ; LOW copy surface pressure to deco routine + ; simulator mode: set surface pressure to 1 bar because simulated depths are also based on 1 bar surface pressure + movlw LOW .1000 + movff WREG,int_I_pres_surface+0 ; LOW copy surface pressure to deco routine movlw HIGH .1000 movff WREG,int_I_pres_surface+1 ; HIGH copy surface pressure to deco routine diveloop_boot_2: - SAFE_2BYTE_COPY temperature,minimum_temperature ; Reset Min-Temp registers + SAFE_2BYTE_COPY temperature,minimum_temperature ; reset minimum temperature registers call init_recording_params ; set up all the divisors - bsf ccr_diluent_setup ; For CCR mode (Required to have better gas working) - btfsc FLAG_ccr_mode ; =1: CCR mode (Fixed ppO2 or Sensor) active - bra divemode_boot2 + bsf FLAG_diluent_setup ; for CCR mode (required to have better gas working) + btfsc FLAG_ccr_mode ; =1: CCR mode (fixed ppO2 or Sensor) active + bra diveloop_boot_3 btfsc FLAG_pscr_mode - bra divemode_boot2 - bcf ccr_diluent_setup ; For OC mode (Required to have better gas working) - -divemode_boot2: + bra diveloop_boot_3 + bcf FLAG_diluent_setup ; for OC mode (required to have better gas working) + +diveloop_boot_3: bcf LEDg ; switch off green LED / release reset to RX circuitry - bcf LEDr ; switch off red LED + bcf LEDr ; switch off red LED bcf realdive - btfss simulatormode_active ; do not disable in simulator mode! - call disable_rs232 ; Disable RS232 - btfsc enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (Screen dump) - call enable_rs232 ; Also sets to speed_normal ... - ; Reset divetime seconds - movlw .2 ; Start at 2seconds - movwf total_divetime_seconds+0 + btfss simulatormode_active ; in simulator mode? + call disable_rs232 ; NO - disable RS232 + + IFDEF _screendump + btfsc enable_screen_dumps ; =1: ignore vin_usb, wait for "l" command (screen dump) + call enable_rs232 ; also sets to speed_normal + ENDIF + + ; reset dive time seconds +; movlw .2 ; start at 2 seconds +; movwf total_divetime_seconds+0 +; clrf total_divetime_seconds+1 +; movwf divesecs +; movwf apnoe_secs +; bsf divemode2 ; displayed dive time is running (dive time starts HERE) + + ; clear the timers (start dive times at zero) + clrf total_divetime_seconds+0 clrf total_divetime_seconds+1 - movwf divesecs - movwf apnoe_secs - bsf divemode2 ; displayed divetime is running (Divetime starts HERE) - return ; Done with divemode boot - + clrf divesecs + clrf divemins+0 + clrf divemins+1 + clrf apnoe_secs + clrf apnoe_mins + + ; divemode2 flag will be set by pressure & timeout evaluation in function set_dive_modes + + return ; done with dive mode boot + + +;============================================================================= divemode_check_for_warnings: - movlw .1 ; One warning at a time in alt. layout mode + movlw .1 ; one message at a time in alternative layout btfss alternative_divelayout - movlw .2 ; Two warnings at a time in default layout mode - cpfsgt warning_counter ; only one (or two) warnings active? - bra divemode_check_for_warnings1 ; Yes, update every second - - btfss secs,0 ; Every two seconds... + movlw .2 ; two messages at a time in default layout + cpfsgt message_counter ; only one (or two) messages active? + bra divemode_check_for_warnings1; YES - update every second + + btfss secs,0 ; every two seconds... return - btfss secs,1 ; Every four seconds... + btfss secs,1 ; every four seconds... return divemode_check_for_warnings1: - bcf warning_active ; Clear flag - clrf warning_counter ; Clear counter - - ; warnings sorted by severity, highest severity first - - ; Warnings for all modes - call check_warn_battery ; Check if the battery level should be displayed/warned - call check_divetimeout ; Not actually a warning. Check and show the divemode timeout - - btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode - bra divemode_check_for_warnings2 - btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode - bra divemode_check_for_warnings2 - - ; Warnings only in deco modes + bcf message_advice ; clear flag for messages of level advice + bcf message_attention ; clear flag for messages of level attention + bcf message_warning ; clear flag for messages of level warning + clrf message_counter ; clear message counter + + ; messages sorted by severity: highest severity warnings first, then attentions, advices and last info + + ; warnings for all modes + call check_warn_battery ; check if the battery level should be displayed/warned + call check_divetimeout ; check and show the dive mode timeout (not actually a warning) + + btfsc FLAG_apnoe_mode ; in Apnoe mode? + bra divemode_check_for_warnings2; YES + btfsc FLAG_gauge_mode ; in gauge mode? + bra divemode_check_for_warnings2; YES + + ; warnings applicable only in deco modes rcall check_ppO2 ; check ppO2 and displays warning, if required btfss sensors_agree ; are the sensor values within the threshold range? @@ -2318,118 +2545,133 @@ btfsc sensors_agree ; are the sensor values within the threshold range? bcf sensor_warning ; YES - revoke memorized sensor warning - movff char_O_deco_warnings,WREG ; bank-safe copy for deco warnings - btfsc WREG,outside_warning_lock ; are we outside of the ZH-L16 model? - rcall warn_outside ; YES + rcall check_outside ; check of ZHL16 model violation rcall check_IBCD ; check for IBCD attention or warning - btfsc decostop_active ; In deco mode? - rcall check_and_store_gf_violation; Yes, sets warnings, if required - - movff char_O_deco_warnings,WREG ; bank-safe copy for deco warnings - btfsc WREG,mbubble_warning_lock ; do we have a microbubbles warning? - rcall warn_mbubbles ; YES + rcall check_OC_gas_avail ; check if a breathable OC gas is available + + btfsc decostop_active ; in deco mode? + rcall check_and_store_gf_violation; YES - sets warnings, if required + + rcall check_mbubbles ; check for micro bubbles rcall check_cns_violation ; Check CNS value and display it, if required - ;btfsc decostop_active ; In deco mode? - rcall check_gas_needs ; show gas needs warning if any gas need is > threshold - - rcall check_eod_cns_violation ; Check CNS values for end-of-dive and display warning, if required - - call TFT_display_ftts ; Show @+x time - - btfsc use_agf ; In aGF mode? - rcall warn_agf ; Yes, show a warning for it - - btfsc setpoint_fallback ; =1: Fallback to SP1 due to external O2 sensor failure - rcall warn_fallback ; Show the warning + rcall check_gas_needs_ascent ; show gas needs warning if any gas need for ascent is > threshold + + rcall check_eod_cns_violation ; check CNS values for end-of-dive and display warning, if required + + rcall check_display_ftts ; show @+x time + + IFDEF _cave_mode + btfsc FLAG_cave_mode ; cave mode enabled? + rcall check_cavemode ; YES - check cave mode status + ENDIF + + btfsc use_agf ; in aGF mode? + rcall warn_agf ; YES - show memo + + btfsc setpoint_fallback ; fallback to SP1 due to external O2 sensor failure? + rcall warn_fallback ; YES - show a warning + + btfsc better_dil_available ; is a better diluent available? + rcall advice_gas_change ; YES - display an advice + btfsc better_gas_available ; is a better gas available? + rcall advice_gas_change ; YES - display an advice divemode_check_for_warnings2: -; Display the warning icon? - btfsc warning_active ; Any warning active? - bsf FLAG_TFT_divemode_warning ; Yes - btfss warning_active ; Any warning active? - bsf FLAG_TFT_divemode_warning_clear ; No, clear warning icon - -; Setup warning_page number - incf warning_page,F - movf warning_page,W + IFDEF _rx_functions + btfss FLAG_tr_enabled ; TR functions enabled? + bra divemode_check_for_warnings3 ; NO - skip + call check_tr_functions ; YES - check transmitter functions + call check_tr_messages ; - check SAC attention and switch advice + ENDIF + +divemode_check_for_warnings3: + ; Display the attention or warning icon? + btfsc message_advice ; any message of level advice? + bsf FLAG_TFT_divemode_warning ; YES + btfsc message_attention ; any message of level attention? + bsf FLAG_TFT_divemode_warning ; YES + btfsc message_warning ; any message of level warning? + bsf FLAG_TFT_divemode_warning ; YES + btfss FLAG_TFT_divemode_warning ; any message of above levels? + bsf FLAG_TFT_divemode_warning_clear ; NO - clear warning icon + + ; Setup message page number + incf message_page,F + movf message_page,W bcf STATUS,C - btfss alternative_divelayout - rlcf warning_page,W ; *2 (But only in standard layout mode) - cpfsgt warning_counter ; > warning_counter - clrf warning_page ; No, clear - -; Clear both rows of warnings if there is nothing to show at all - tstfsz warning_counter ; any warnings? - bra divemode_check_for_warnings3 ; YES - look if second row needs to be cleared - bsf FLAG_TFT_dive_warning_text_clear ; Set flag + btfss alternative_divelayout ; in alternative layout? + rlcf message_page,W ; NO - *2 + cpfsgt message_counter ; > message_counter? + clrf message_page ; NO - clear + + ; Clear both rows of messages if there is nothing to show at all + tstfsz message_counter ; any messages? + bra divemode_check_for_warnings4 ; YES - look if second row needs to be cleared + bsf FLAG_TFT_dive_warning_text_clear; set flag return -divemode_check_for_warnings3: - - -; Clear 2nd row of warnings if there is nothing to show (on this page) - btfss second_row_warning ; =1: The second row contains a warning - bsf FLAG_TFT_dive_warning_text_clr2 ; Set flag for 2nd row - return ; Done. + +divemode_check_for_warnings4: + ; Clear 2nd row of messages if there is nothing to show (on this page) + btfss second_row_warning ; =1: the second row contains a warning + bsf FLAG_TFT_dive_warning_text_clr2 ; set flag for 2nd row + return ; done global check_warn_battery check_warn_battery: movff batt_percent,lo movlw battery_show_level+1 - cpfslt lo - return ; No Display, no warning + cpfslt lo ; battery percentage ok? + return ; YES - no display, no warning ; Display Battery, but warn? movff batt_percent,lo movlw color_code_battery_low+1 - cpfsgt lo - bsf warning_active ; Set Warning flag - - movlw .4 - cpfseq menupos3 ; battery shown in Custom View 4? - bra check_warn_battery2 ; No - return ; Yes, do not show twice (in custom view and in warning area) + cpfsgt lo ; battery percent below warning threshold? + bsf message_warning ; YES - set warning flag + btfsc alternative_divelayout ; in alternative layout? + bra check_warn_battery2 ; YES - show warning + movlw index_clock_batt_surfpress ; NO - index of custom view clock, battery and surface pressure + cpfseq menupos3 ; - battery shown in custom view? + bra check_warn_battery2 ; NO - show warning + return ; YES - do not show twice (in custom view and in message area) check_warn_battery2: - incf warning_counter,F ; increase counter - goto TFT_update_batt_percent_divemode ; Show percent (And return) + incf message_counter,F ; increase counter + goto TFT_update_batt_percent_divemode ; show percent (and return) check_divetimeout: - btfsc divemode2 - return ; displayed divetime is not running - incf warning_counter,F ; increase counter - goto TFT_divetimeout ; Show timeout counter (and return) - + btfsc divemode2 ; dive time running? + return ; YES - do nothing + incf message_counter,F ; increase counter + goto TFT_divetimeout ; show timeout counter (and return) check_ppO2: - btfsc FLAG_ccr_mode ; are we in CCR mode? - bra check_ppO2_loop ; YES - btfsc FLAG_pscr_mode ; are we in pSCR mode? - bra check_ppO2_loop ; YES - bra check_ppO2_oc_1 ; NO - neither CCR nor pSCR -check_ppO2_loop: - btfsc is_bailout ; in bailout? - bra check_ppO2_oc_1 ; YES - continue with OC - movff int_O_pure_ppO2+1,hi ; NO - get upper part of int_O_pure_ppO2 - btfsc hi,int_warning_flag ; ppO2 of the pure diluent to low or high? - rcall check_ppo2_display ; YES - show warning and return on next line - btfsc hi,int_attention_flag ; ppO2 of the pure diluent close to setpoint? - rcall check_ppo2_display ; YES - show warning and return on next line - bra check_ppO2_oc_2 ; skip attention threshold test on breathed ppO2 -check_ppO2_oc_1: - movff int_O_breathed_ppO2+1,WREG ; get upper part of int_O_breathed_ppO2 - btfsc WREG,int_attention_flag ; breathed ppO2 just above attention threshold? - bra check_ppo2_display ; YES - show ppO2 -check_ppO2_oc_2: - movff int_O_breathed_ppO2+1,WREG ; get upper part of int_O_breathed_ppO2 (perhaps again) - btfsc WREG,int_low_flag ; breathed ppO2 to low? + btfsc FLAG_oc_mode ; are we in OC mode? + bra check_ppO2_1 ; YES - continue with breathed gas + btfsc FLAG_bailout_mode ; NO - in bailout? + bra check_ppO2_1 ; YES - continue with breathed gas + ; CCR / pSCR mode - checks on pure diluent + movff int_O_pure_ppO2+0,lo ; get value and attention/warning flags for the pure diluent + movff int_O_pure_ppO2+1,hi ; + btfsc hi,int_warning_flag ; ppO2 of the pure diluent to low or high? + rcall check_ppO2_dw ; YES - show warning and return on next line + btfsc hi,int_attention_flag ; ppO2 of the pure diluent in attention state? + rcall check_ppO2_da ; YES - show attention and return on next line + ; all modes - checks on breathed gas (OC or from loop) +check_ppO2_1: + movff int_O_breathed_ppO2+0,lo ; get value and attention/warning flags for the breathed gas + movff int_O_breathed_ppO2+1,hi ; get warnings for breathed gas + btfsc hi,int_attention_flag ; breathed ppO2 in attention state (when in loop mode, no attention will be generated)? + bra check_ppo2_display_a ; YES - set attention flag and show ppO2 + btfsc hi,int_low_flag ; breathed ppO2 to low? bra check_ppO2_low ; YES - record the warning and show ppO2 - btfsc WREG,int_high_flag ; breathed ppO2 to high? + btfsc hi,int_high_flag ; breathed ppO2 to high? bra check_ppO2_high ; YES - record the warning and show ppO2 TSTOSS opt_showppo2 ; show ppO2 anyhow? (0 = no, 1 = show always) - return ; NO - no warnings, no show - bra check_ppo2_display ; YES - just show ppO2 + return ; NO - no warnings, no show - done + bra check_ppO2_common_2 ; YES - but only when in OC or bailout... check_ppO2_low: movlw d'4' ; set type of alarm (ppO2 low) bra check_ppO2_common ; continue with common part @@ -2437,37 +2679,47 @@ movlw d'5' ; set type of alarm (ppO2 high) check_ppO2_common: movwf AlarmType ; copy alarm type to alarm register - bsf event_occured ; set event flag - bsf warning_active ; set warning flag - btfsc is_bailout ; are we in bailout? - bra check_ppo2_display ; YES - skip CCR/pSCR checks - btfsc FLAG_ccr_mode ; are we in CCR mode? - return ; YES - no extra warning required - btfsc FLAG_pscr_mode ; are we in pSCR mode? - return ; YES - no extra warning required -check_ppo2_display: ; display warning if ppO2 is not already shown in custom view - movlw .9 - cpfseq menupos3 ; ppO2 shown in Custom View 9? - bra check_ppO2_a ; No - return ; Yes, do not show twice (in custom view and in warning area) -check_ppO2_a: - movlw .11 - cpfseq menupos3 ; ppO2 shown in Custom View 11? - bra check_ppO2_b ; No - return ; Yes, do not show twice (in custom view and in warning area) + bsf event_occured ; set event flag + bsf message_warning ; show warning sign +check_ppO2_common_2: + btfsc FLAG_oc_mode ; are we in OC mode? + bra check_ppo2_display ; YES + btfsc FLAG_bailout_mode ; are we in bailout mode? + bra check_ppo2_display ; YES + return ; NO - in loop mode, ppO2 is already shown via setpoint display +check_ppo2_display_a: + bsf message_attention ; show attention sign +check_ppo2_display: + btfsc alternative_divelayout ; in alternative layout? + bra check_ppO2_d ; YES - show warning + movlw index_ppo2_ead_end_cns ; NO - index of custom view ppO2, EAD/END and CNS) + cpfseq menupos3 ; ppO2 shown? + bra check_ppO2_b ; NO + return ; YES - do not show twice (in custom view and in warning area) check_ppO2_b: - movlw .12 - cpfseq menupos3 ; ppO2 shown in Custom View 12? - bra check_ppO2_c ; No - return ; Yes, do not show twice (in custom view and in warning area) -check_ppO2_c: - movlw .10 - cpfseq menupos3 ; ppO2 shown in Custom View 10? - bra check_ppO2_d ; No - return ; Yes, do not show twice (in custom view and in warning area) + movlw index_pscr_info ; index of custom view with pSCR data + cpfseq menupos3 ; ppO2 shown? + bra check_ppO2_d ; NO - show warning + return ; YES - do not show twice (in custom view and in warning area) +check_ppO2_dw: + bsf message_warning ; show warning sign +check_ppO2_da: + bsf message_attention ; show attention sign (no problem if a warning sign is set as well, as it will take priority) check_ppO2_d: - incf warning_counter,F ; increase counter - goto TFT_display_ppo2 ; show breathed gas or diluent ppO2 warning (and return) + incf message_counter,F ; increase counter + goto TFT_display_ppo2_warning ; show breathed gas or diluent ppO2 warning (and return) + + +check_display_ftts: + movff char_I_extra_time,lo ; get extra time + tstfsz lo ; extra time > 0 ? + bra check_display_ftts_1 ; YES - continue checking bailout condition + return ; NO - done +check_display_ftts_1: + btfsc FLAG_bailout_mode ; in bailout mode? + return ; YES - in bailout no fTTS will be computed, so nothing to display + incf message_counter,F ; NO - increase counter + goto TFT_display_ftts ; - show @+x time global check_cns_violation @@ -2475,32 +2727,35 @@ ; Check if CNS should be displayed movff int_O_CNS_fraction+1,WREG ; get high byte btfsc WREG,int_warning_flag ; warning flag set? - bra check_cns_violation2 ; Yes - issue warning - btfsc WREG,int_attention_flag ; attention flag set? - bra display_cns_violation ; YES - just display CNS - return ; No - no display, no warning -check_cns_violation2: - bsf warning_active ; Set Warning flag -display_cns_violation: ; Show CNS if not shown in the custom view - movlw .11 - cpfseq menupos3 ; CNS shown in Custom View? - bra display_cns_violation2 ; No - return ; Yes, do not show twice (in custom view and in warning area) -display_cns_violation2: - movlw .8 - cpfseq menupos3 ; CNS shown through Custom View 8 right now? - bra display_cns_violation3 ; No - return ; Yes, do not show twice (in custom view and in warning area) -display_cns_violation3: - incf warning_counter,F ; increase counter - goto TFT_display_cns ; Show CNS (and return) + bra check_cns_violation_1 ; YES - issue warning + btfsc WREG,int_attention_flag ; NO - attention flag set? + bra check_cns_violation_2 ; YES - issue attention + return ; NO - done +check_cns_violation_1: + bsf message_warning ; show warning sign +check_cns_violation_2: + bsf message_attention ; show attention sign + btfsc alternative_divelayout ; in alternative layout? + bra check_cns_violation_4 ; YES - show attention + movlw index_ppo2_ead_end_cns ; NO - index of custom view ppO2, EAD/END and CNS + cpfseq menupos3 ; - CNS shown? + bra check_cns_violation_3 ; NO + return ; YES - do not show twice (in custom view and in warning area) +check_cns_violation_3: + movlw index_CNS ; index of custom view with CNS values + cpfseq menupos3 ; CNS shown? + bra check_cns_violation_4 ; NO + return ; YES - do not show twice (in custom view and in warning area) +check_cns_violation_4: + incf message_counter,F ; increase counter + goto TFT_display_cns ; show CNS (and return) global check_eod_cns_violation ; check end-of-dive CNS values check_eod_cns_violation: movff int_O_CNS_fraction+1,WREG ; get high-byte of current CNS value btfsc WREG,int_warning_flag ; current CNS value in warning state? - return ; YES - inhibit eod warning if current CNS is already in warning + return ; YES - inhibit end-of-dive warning if current CNS is already in warning movff int_O_normal_CNS_fraction+1,WREG btfsc WREG,int_invalid_flag ; flag for invalid value set? bra check_eod_cns_violation1 ; YES - continue with checking the other CNS value @@ -2511,16 +2766,18 @@ btfsc WREG,int_invalid_flag ; flag for invalid value set? return ; YES - done with CNS checking btfsc WREG,int_warning_flag ; NO - flag for warning set? - bra check_eod_cns_violation2 ; Yes - issue warning + bra check_eod_cns_violation2 ; YES - issue warning return ; NO - done with CNS checking -check_eod_cns_violation2: ; YES - issue warning - bsf warning_active ; set Warning flag - movlw .8 ; issue textual warning if CNS values are not shown in the custom view right now - cpfseq menupos3 ; CNS values shown through Custom View 8 right now? - bra display_eod_cns_violation ; NO - issue textual warning - return ; YES - do not show twice (in custom view and in warning area) +check_eod_cns_violation2: ; issue warning (actually only on attention level) + bsf message_attention ; show attention sign + btfsc alternative_divelayout ; in alternative layout? + bra display_eod_cns_violation ; YES - show warning + movlw index_CNS ; NO - index of custom view with CNS values + cpfseq menupos3 ; - CNS values shown? + bra display_eod_cns_violation ; NO - issue textual warning + return ; YES - do not show twice (in custom view and in warning area) display_eod_cns_violation: - incf warning_counter,F ; increase counter + incf message_counter,F ; increase counter goto TFT_display_eod_cns ; issue CNS at end-of-dive warning (and return) @@ -2532,7 +2789,7 @@ movlw d'2' ; YES - set type of alarm movwf AlarmType ; copy to alarm register bsf event_occured ; set event flag - bsf warning_active ; set warning flag + bsf message_warning ; set warning flag bra check_and_store_gf_violation3 ; show gf warning check_and_store_gf_violation2: btfsc WREG,int_attention_flag ; check if the attention flag is set @@ -2543,56 +2800,268 @@ btfss WREG,IBCD_warning ; is the IBCD warning flag set? bra check_and_store_gf_violation4 ; NO - continue checking for deco info check_and_store_gf_violation3: ; YES - show gf - bsf warning_active ; set Warning flag - incf warning_counter,F ; increase counter + bsf message_attention ; show attention sign + incf message_counter,F ; increase counter goto TFT_warning_gf ; show GF (and return) check_and_store_gf_violation4: ; check for deco info - btfss divemode ; in divemode? + btfss divemode ; in dive mode? return ; NO - done, return - movff char_O_deco_warnings,WREG ; YES - get the deco warnings vector - btfss WREG,deco_flag ; check if the deco flag is set - return ; NO - all done, return - incf warning_counter,F ; YES - increase counter - goto TFT_info_deco ; show deco info - - -warn_outside: - incf warning_counter,F ; increase counter - bsf warning_active ; Set Warning flag - goto TFT_warning_outside ; show outside warning (and return) - - - global warn_mbubbles -warn_mbubbles: - incf warning_counter,F ; increase counter - bsf warning_active ; Set Warning flag - goto TFT_warning_mbubbles ; show microbubbles warning (and return) - + btfsc FLAG_bailout_mode ; YES - in bailout mode? + return ; YES - done, return (deco_decreasing flag is not updated when in bailout mode) + movff char_O_deco_info,WREG ; NO - get the deco info vector + btfss WREG,deco_decreasing ; check if the deco_decreasing flag is set + return ; NO - done, return + incf message_counter,F ; YES - increase counter + goto TFT_info_deco ; - show deco info + + +check_outside: + movff char_O_deco_warnings,WREG ; bank-safe copy of deco warnings + btfss WREG,outside_warning_lock ; are we outside of the ZH-L16 model? + return ; NO - done + incf message_counter,F ; YES - increase counter + bsf message_attention ; - show attention sign + btfsc WREG,outside_warning ; - are we outside the ZH-L16 model right now (-> warning)? + bsf message_warning ; - set warning flag + goto TFT_warning_outside ; - show outside-ZHL-model warning/attention (and return) + + + global check_mbubbles +check_mbubbles: + movff char_O_deco_warnings,WREG ; bank-safe copy for deco warnings + btfsc WREG,mbubble_warning ; are we in micro bubbling zone right now? + bra check_mbubbles_warn ; YES + btfss WREG,mbubble_warning_lock ; were we in micro bubbling zone? + return ; NO - done +check_mbubble_att ; YES - attention level + incf message_counter,F ; increase counter + bsf message_attention ; show attention sign + goto TFT_warning_mbubbles ; show micro bubble attention (and return) - TFT_warning_mbubbles switches by itself between attention and warning +check_mbubbles_warn: ; locked micro bubbles - warning level if at issue, attention level if locked + incf message_counter,F ; increase counter + bsf message_warning ; set warning flag + goto TFT_warning_mbubbles ; show micro bubbles warning (and return) + + IFDEF _cave_mode +check_cavemode: + incf message_counter,F ; increase counter + btfsc FLAG_dive_turned ; dive turned? + goto TFT_info_dive_turned ; YES - show info that dive is turned + btfsc FLAG_cave_mode_shutdown ; NO - has cave mode shut down? + goto TFT_warn_cave_shutdown ; YES - show that cave mode has shut down + goto TFT_info_cave_mode ; NO - show that cave mode is active + ENDIF + warn_agf: - incf warning_counter,F ; increase counter - goto TFT_warning_agf ; Show aGF warning (and return) + incf message_counter,F ; increase counter + goto TFT_warning_agf ; show aGF warning (and return) warn_fallback: - incf warning_counter,F ; increase counter - bsf warning_active ; Set Warning flag - goto TFT_warning_fallback ; Show fallback warning (and return) - - -check_gas_needs: - banksel int_O_tank_pres_need - movf int_O_tank_pres_need+1,w ; get HIGH(pres need of 1st tank) - iorwf int_O_tank_pres_need+3,w ; inclusive or with HIGH(pres need of 2nd tank) - iorwf int_O_tank_pres_need+5,w ; inclusive or with HIGH(pres need of 3rd tank) - iorwf int_O_tank_pres_need+7,w ; inclusive or with HIGH(pres need of 4th tank) - iorwf int_O_tank_pres_need+9,w ; inclusive or with HIGH(pres need of 5th tank) + incf message_counter,F ; increase counter + bsf message_warning ; set warning flag + goto TFT_warning_fallback ; show fallback warning (and return) + + + IFDEF _rx_functions + +check_tr_messages: + movff int_O_sac_rate+1,WREG ; bank-safe copy of current SAC rate + btfss WREG,int_attention_flag ; attention flag set? + bra check_tr_messages2 ; NO - skip + btfsc WREG,int_not_avail_flag ; SAC rate available? + bra check_tr_messages2 ; NO - continue with swap advice + bsf message_attention ; YES - show attention sign + btfsc alternative_divelayout ; - in alternative layout? + bra check_tr_messages1 ; YES - show attention message + movlw index_pressures_SAC ; NO - index of custom view with SAC rate + cpfseq menupos3 ; - SAC rate shown right now? + bra check_tr_messages1 ; NO - show attention message + bra check_tr_messages2 ; YES - do not show twice, continue with swap advice +check_tr_messages1: + incf message_counter,F ; increase counter + call TFT_attention_sac ; show SAC attention +check_tr_messages2: + movff char_O_deco_info,WREG ; bank-safe copy of deco info vector + btfss WREG,ind_double_switch ; swap tank flag set? + return ; NO + incf message_counter,F ; YES - increase counter + bsf message_advice ; - show advice sign + goto TFT_advice_switch ; - show swap advice + + +#DEFINE show_custview ul,0 ; show pressure readings custom view +#DEFINE show_transmitter ul,1 ; show transmitter attention +#DEFINE show_pres_warning ul,2 ; show transmitter pressure warning +#DEFINE show_pres_attention ul,3 ; show transmitter pressure attention + +check_tr_functions: + clrf ul ; set all messages as not shown yet + btfsc alternative_divelayout ; in alternative layout? + bra check_tr_functions_tr1 ; YES - continue with checking transmitter 1 + movlw index_pressures_SAC ; NO - index of custom view pressure readings + cpfseq menupos3 ; - pressure readings shown? + bra check_tr_functions_tr1 ; NO - continue with checking transmitter 1 + bsf show_custview ; YES - suppress redraw by faking it has already been redrawn +check_tr_functions_tr1: + movff char_I_pressure_stat+0,WREG ; get status of 1st pressure reading + rcall check_tr_functions_helper1 ; check for transmitter 1 lost + rcall check_tr_functions_helper2 ; check for transmitter 1 low battery + movff int_IO_pressure_value+1,WREG ; get high byte of 1st pressure reading + rcall check_tr_functions_helper3 ; check for transmitter 1 pressure warning + rcall check_tr_functions_helper4 ; check for transmitter 1 pressure attention +check_tr_functions_tr2: + movff char_I_pressure_stat+1,WREG ; get status of 2nd pressure reading + rcall check_tr_functions_helper5 ; check for transmitter 2 lost + rcall check_tr_functions_helper6 ; check for transmitter 2 low battery + movff int_IO_pressure_value+3,WREG ; get high byte of 2nd pressure reading + rcall check_tr_functions_helper7 ; check for transmitter 2 pressure warning + rcall check_tr_functions_helper8 ; check for transmitter 2 pressure attention +check_tr_functions_show_xmtr: + btfss show_transmitter ; shall show transmitter message? + bra check_tr_functions_show_warn ; NO - continue with pressure warning + bsf message_attention ; YES - set flag for attention + incf message_counter,F ; - increase counter + call TFT_attention_transmitter ; - show transmitter attention message +check_tr_functions_show_warn: + btfss show_pres_warning ; shall show pressure warning? + bra check_tr_functions_show_att ; NO - continue with pressure attention + bsf message_warning ; YES - set flag for warning + incf message_counter,F ; - increase counter + goto TFT_warning_pres_reading ; - pressure reading warning message and done then +check_tr_functions_show_att: + btfss show_pres_attention ; shall show pressure attention? + return ; NO - done + bsf message_attention ; YES - set flag for attention + incf message_counter,F ; - increase counter + goto TFT_attention_pres_reading ; - pressure reading warning message and done then + +check_tr_functions_helper1: + btfsc WREG,char_transmitter_lost ; transmitter 1 lost? + bra check_tr_functions_helper1a ; YES - show transmitter attention message + bcf transmitter1_lost ; NO - clear flag for old lost attention + return ; - done +check_tr_functions_helper1a: + bsf show_transmitter ; show transmitter attention + btfsc transmitter1_lost ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter1_lost ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper2: + btfsc WREG,char_transmitter_low_bat ; transmitter 1 low battery? + bra check_tr_functions_helper2a ; YES - show transmitter attention message + bcf transmitter1_battery ; NO - clear flag for old battery attention + return ; - done +check_tr_functions_helper2a: + bsf show_transmitter ; show transmitter attention + btfsc transmitter1_battery ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter1_battery ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper3: + btfsc WREG,int_warning_flag ; transmitter 1 pressure warning? + bra check_tr_functions_helper3a ; YES - show pressure reading message as warning + bcf transmitter1_pres_warn ; NO - clear flag for old warning + return ; - done +check_tr_functions_helper3a: + bsf show_pres_warning ; show pressure warning + btfsc transmitter1_pres_warn ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter1_pres_warn ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper4: + btfsc WREG,int_attention_flag ; transmitter 1 pressure attention? + bra check_tr_functions_helper4a ; YES - show pressure reading message as attention + bcf transmitter1_pres_att ; NO - clear flag for old attention + return ; - done +check_tr_functions_helper4a + bsf show_pres_attention ; show pressure attention + btfsc transmitter1_pres_att ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter1_pres_att ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper5: + btfsc WREG,char_transmitter_lost ; transmitter 2 lost? + bra check_tr_functions_helper5a ; YES - show transmitter attention message + bcf transmitter2_lost ; NO - clear flag for old lost attention + return ; - done +check_tr_functions_helper5a: + bsf show_transmitter ; show transmitter attention + btfsc transmitter2_lost ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter2_lost ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper6: + btfsc WREG,char_transmitter_low_bat ; transmitter 2 low battery? + bra check_tr_functions_helper6a ; YES - show transmitter attention message + bcf transmitter2_battery ; NO - clear flag for old battery attention + return ; - done +check_tr_functions_helper6a: + bsf show_transmitter ; show transmitter attention + btfsc transmitter2_battery ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter2_battery ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper7: + btfsc WREG,int_warning_flag ; transmitter 2 pressure warning? + bra check_tr_functions_helper7a ; YES - show pressure reading message as warning + bcf transmitter2_pres_warn ; NO - clear flag for old warning + return ; - done +check_tr_functions_helper7a: + bsf show_pres_warning ; show pressure warning + btfsc transmitter2_pres_warn ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter2_pres_warn ; YES - memorize it's an old message now + bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_helper8: + btfsc WREG,int_attention_flag ; transmitter 2 pressure attention? + bra check_tr_functions_helper8a ; YES - show pressure reading message as attention + bcf transmitter2_pres_att ; NO - clear flag for old attention + return ; - done +check_tr_functions_helper8a + bsf show_pres_attention ; show pressure attention + btfsc transmitter2_pres_att ; is it a new message? + return ; NO - do not show the pressure readings custom view again + bsf transmitter2_pres_att ; YES - memorize it's an old message now + ;bra check_tr_functions_show_cv ; - show custom view + +check_tr_functions_show_cv: + btfsc show_custview ; is the pressure readings custom view not shown yet shown? + return ; NO - already shown, done + bsf show_custview ; YES - mark as shown + btfsc alternative_divelayout ; - in alternative layout? + call switch_layout_to_normal ; YES - switch to normal layout + movlw index_pressures_SAC-1 ; custom view number one below pressure readings + movwf menupos3 ; set custom view number + bsf toggle_customview ; initiate toggle to desired custom view -> pressure readings view will be shown + return ; done + + ENDIF + + +check_gas_needs_ascent: + banksel int_O_ascent_pres_need + movf int_O_ascent_pres_need+1,w ; get high byte from pres need of 1st tank + iorwf int_O_ascent_pres_need+3,w ; inclusive or with high byte from pres need of 2nd tank + iorwf int_O_ascent_pres_need+5,w ; inclusive or with high byte from pres need of 3rd tank + iorwf int_O_ascent_pres_need+7,w ; inclusive or with high byte from pres need of 4th tank + iorwf int_O_ascent_pres_need+9,w ; inclusive or with high byte from pres need of 5th tank banksel common btfsc WREG,int_invalid_flag ; check if invalid flag is set return ; YES - no further checking required - btfsc WREG,int_warning_flag ; NO - check if any gas has a pres_need >= pres_fill - bsf warning_active ; YES - set warning flag - btfsc WREG,int_warning_flag ; NO - check if any gas has a pres_need >= pres_fill + btfsc WREG,int_warning_flag ; check if any gas has a pres_need >= pres_fill + bsf message_warning ; YES - set warning flag + btfsc WREG,int_warning_flag ; check if any gas has a pres_need >= pres_fill goto TFT_warning_gas_needs_warn ; Yes - show a warning - btfsc WREG,int_attention_flag ; NO - check if any gas has a pres_need >= pres_fill * threshold + btfsc WREG,int_attention_flag ; check if any gas has a pres_need >= pres_fill * threshold + bsf message_attention ; YES - set attention flag + btfsc WREG,int_attention_flag ; check if any gas has a pres_need >= pres_fill * threshold goto TFT_warning_gas_needs_att ; YES - show an attention bcf gas_needs_attention ; NO - clear flag for a new attention bcf gas_needs_warning ; clear flag for a new warning @@ -2600,8 +3069,8 @@ check_warn_sensors_disagree: - incf warning_counter,F ; increase counter - bsf warning_active ; YES - set Warning flag + incf message_counter,F ; increase counter + bsf message_warning ; YES - set warning flag goto TFT_warning_sensor_disagree ; show sensor disagree warning (and return) @@ -2611,75 +3080,119 @@ movff char_O_deco_warnings,WREG ; YES - get deco warnings vector btfss WREG,IBCD_warning ; IBCD warning flag set? return ; NO - return - incf warning_counter,F ; YES - increase counter + incf message_counter,F ; YES - increase counter goto TFT_warning_IBCD ; write warning to display +check_OC_gas_avail: + tstfsz best_gas_number ; is a breathable gas available? + return ; > 0 : a breathable gas is available + btfsc FLAG_ccr_mode ; = 0 : problem - in CCR mode? + bra check_OC_gas_avail_1 ; YES - real problem + btfsc FLAG_pscr_mode ; NO - in PSCR mode? + bra check_OC_gas_avail_1 ; YES - real problem + return ; NO - neither CCR nor pSCR mode, suppress warning +check_OC_gas_avail_1: + btfsc FLAG_bailout_mode ; in bailout? + return ; YES - suppress warning + incf message_counter,F ; NO - increase counter + bsf message_attention ; set attention flag + goto TFT_warning_no_BO_gas ; show message (and return) + + +advice_gas_change: + bsf message_advice ; show advice sign + incf message_counter,F ; increase counter + goto TFT_advice_gas_change + + global restart_deco_engine global restart_deco_engine_wo_ceiling restart_deco_engine: - ; make bank save copies and set flags for invalid data + ; invalidate ceiling movff int_O_ceiling+1,WREG bsf WREG,char_invalid_flag ; int_O_ceiling has its invalid flag on a char's position! movff WREG,int_O_ceiling+1 restart_deco_engine_wo_ceiling: - ; make more bank save copies and set more flags for invalid data + ; invalidate deco data (stop table data) movff char_O_deco_gas+0,WREG bsf WREG,char_invalid_flag movff WREG,char_O_deco_gas+0 + ; invalidate ascent time (normal plan) movff int_O_ascenttime+1,WREG bsf WREG,int_invalid_flag movff WREG,int_O_ascenttime+1 - movff int_O_alternate_ascenttime+1,WREG - bsf WREG,int_invalid_flag - movff WREG,int_O_alternate_ascenttime+1 - + ; invalidate CNS at end of dive in normal plan movff int_O_normal_CNS_fraction+1,WREG bsf WREG,int_invalid_flag movff WREG,int_O_normal_CNS_fraction+1 + ; restart deco engine + movff char_O_main_status,WREG ; get current main engine configuration + bcf WREG,DECO_COMPLETED_NORM ; eventually clear flag stating completion of normal plan + bsf WREG,DECO_COMPLETED_ALT ; fake we came from alternative plan to force normal plan to be done next + movff WREG,char_O_main_status ; write back new configuration + movff char_O_deco_status,WREG ; get current deco engine status + bcf WREG,DECO_STATUS_0_FLAG ; set status flags to... + bcf WREG,DECO_STATUS_1_FLAG ; ... DECO_STATUS_START + movff WREG,char_O_deco_status ; write back new configuration to restart deco computations + +inval_alternative_plan_data: + ; invalidate ascent time (alternative plan) + movff int_O_alternate_ascenttime+1,WREG + bsf WREG,int_invalid_flag + movff WREG,int_O_alternate_ascenttime+1 + + ; invalidate CNS at end of dive in alternative plan movff int_O_alternate_CNS_fraction+1,WREG bsf WREG,int_invalid_flag movff WREG,int_O_alternate_CNS_fraction+1 - movff int_O_tank_pres_need+1,WREG + ; invalidate ascent gas needs + movff int_O_ascent_pres_need+1,WREG bsf WREG,int_invalid_flag - movff WREG,int_O_tank_pres_need+1 - - ; restart deco engine - movff char_O_deco_status,WREG ; get current deco engine configuration - bcf WREG,DECO_STATUS_0_FLAG ; set status flags to... - bcf WREG,DECO_STATUS_1_FLAG ; ... DECO_STATUS_START - bsf WREG,DECO_PLAN_FLAG ; fake we came from alternative plan to force normal plan to be done next - movff WREG,char_O_deco_status ; write back new configuration to restart deco computations + movff WREG,int_O_ascent_pres_need+1 + + IFDEF _rx_functions + ; invalidate pressure needs (TR functions) + movff int_O_pressure_need+1,WREG + bsf WREG,int_not_avail_flag + movff WREG,int_O_pressure_need+1 + movff int_O_pressure_need+3,WREG + bsf WREG,int_not_avail_flag + movff WREG,int_O_pressure_need+3 + ENDIF + + ; update display depended on NDL or deco mode + bsf FLAG_TFT_display_ndl_or_deko return ;============================================================================= -; simulator mode +; Simulator Mode ; global do_demo_divemode do_demo_divemode: - call option_save_all ; Save all settings into EEPROM before starting simulation + call TFT_ClearScreen ; blank screen + call option_save_all ; save all settings into EEPROM before starting simulation call deco_push_tissues_to_vault ; C-code: back-up status of the real tissues - banksel common ; Bank1 - - ; +++ COMMENTED OUT FOR TESTING PURPOSE ONLY !!! +++ - ; +++ DO NOT COMMENT OUT IN OPERATIONAL USE !!! +++ - ; - bsf restore_deco_data ; Restore tissue and CNS after simulator use + banksel common ; bank 1 + + ; +++ COMMENT OUT FOR TESTING PURPOSE ONLY !!! +++ + bsf restore_deco_data ; restore tissue and CNS after simulator use + ; +++ DO NOT COMMENT OUT IN OPERATIONAL USE !!! +++ bcf pressure_refresh - btfss pressure_refresh ; Wait for sensor + btfss pressure_refresh ; wait for sensor bra $-2 - bsf simulatormode_active ; Set Flag - ; Compute dive ambient conditions - banksel char_I_bottom_depth + bsf simulatormode_active ; set flag + + banksel char_I_bottom_depth ; compute dive ambient conditions movf char_I_bottom_depth,W mullw .100 movff PRODL,rel_pressure+0 @@ -2690,9 +3203,9 @@ movlw HIGH (.1000) addwfc PRODH,W movff WREG,sim_pressure+1 - banksel common ; Bank1 + banksel common ; bank 1 bsf divemode - goto diveloop ; Switch into Divemode! + goto diveloop ; switch into dive mode END \ No newline at end of file