comparison src/divemode.asm @ 0:11d4fc797f74

init
author heinrichsweikamp
date Wed, 24 Apr 2013 19:22:45 +0200
parents
children e402813343b6
comparison
equal deleted inserted replaced
-1:000000000000 0:11d4fc797f74
1 ;=============================================================================
2 ;
3 ; File divemode.asm
4 ;
5 ; Divemode
6 ;
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
8 ;=============================================================================
9 ; HISTORY
10 ; 2011-08-15 : [mH] moving from OSTC code
11
12 #include "ostc3.inc" ; Mandatory header
13 #include "shared_definitions.h" ; Mailbox from/to p2_deco.c
14 #include "tft_outputs.inc"
15 #include "strings.inc"
16 #include "tft.inc"
17 #include "eeprom_rs232.inc"
18 #include "isr.inc"
19 #include "math.inc"
20 #include "wait.inc"
21 #include "customview.inc"
22 #include "start.inc"
23 #include "adc_lightsensor.inc"
24 #include "ghostwriter.inc"
25 #include "i2c.inc"
26
27 gui CODE
28
29 global diveloop
30 diveloop:
31 banksel common
32 call speed_normal
33 call diveloop_boot ; Boot tasks for all modes
34
35 ; Startup Tasks for all modes
36 call TFT_ClearScreen ; clean up TFT
37 call TFT_divemode_mask ; Display mask
38 call TFT_temp_divemode ; Displays temperature
39
40 btfsc FLAG_apnoe_mode
41 bsf realdive ; Set Realdive flag in Apnoe mode
42
43 btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode
44 bra diveloop_loop
45 btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode
46 bra diveloop_loop
47
48 call TFT_active_gas_divemode ; Display gas/Setpoint
49 call TFT_display_ndl_mask ; display "NDL"
50
51 ; +@5 init
52 setf WREG ; WAIT marker: display "---"
53 movff WREG,int_O_extra_ascenttime+0
54 movff WREG,int_O_extra_ascenttime+1
55 movlw 1
56 movwf apnoe_mins ; Start compute after next cycle.
57
58 ;--------------------------------------------------------------------------------------------------------
59 diveloop_loop: ; The diveloop starts here
60 btfss onesecupdate
61 bra diveloop_loop3
62
63 ; tasks any new second...
64 btfsc FLAG_apnoe_mode ; Only in apnoe mode
65 bra diveloop_loop1b ; One Second Tasks in Apnoe mode
66
67 call TFT_divemins ; Display (new) divetime!
68 call customview_second ; Do every-second tasks for the custom view area
69
70 ; Tasks only for deco modes
71 call calc_deko_divemode ; calculate decompression and display result (any two seconds)
72 bra diveloop_loop1x ; Common Tasks
73
74 diveloop_loop1b:
75 ; Tasks only for Apnoe mode
76 call divemode_apnoe_tasks ; 1 sec. Apnoe tasks
77 bra diveloop_loop1x ; Common Tasks
78
79 diveloop_loop1x:
80 ; Common 1sec. tasks for all modes
81 call timeout_divemode ; dive finished? This routine sets the required flags
82 call set_dive_modes ; tests if depth>threshold
83 call set_min_temp ; store min. temp if required
84
85 btfsc store_sample ; store new sample?
86 call store_dive_data ; Store profile data
87
88 btfss divemode ; Dive finished?
89 goto ghostwriter_end_dive ; Dive finished!
90
91 btfsc divemode_gaschange ; Gas switch flag set?
92 rcall gas_switched_common ; Yes
93
94 btfsc toggle_gf ; =1: Toggle GF/aGF
95 rcall divemodemode_togglegf ; Toggle aGF/GF
96
97 ; btfsc FLAG_ccr_mode ; In CCR mode
98 ; call TFT_active_gas_divemode ; Update Setpoint every second
99
100 bcf onesecupdate ; one seconds update done
101
102 diveloop_loop3:
103 rcall test_switches_divemode ; Check switches in divemode
104
105 global diveloop_loop4
106 diveloop_loop4: ; Menu-Exit returns here...
107 btfsc toggle_customview ; Next view?
108 call customview_toggle ; Yes, show next customview (and delete this flag)
109
110 btfsc pressure_refresh ; new pressure available?
111 rcall update_temp_and_or_depth ; Yes, display new depth and clear "pressure_refresh" flag
112
113 btfsc oneminupdate ; one minute tasks
114 rcall update_divemode60 ; Update clock, etc.
115
116 btfss quarter_second_update
117 bra diveloop_loop4a
118 bcf quarter_second_update
119 movlw .6
120 cpfseq menupos3 ; in compass view?
121 bra diveloop_loop4a ; No
122 call TFT_dive_compass_heading ; Yes, update compass heading value
123 diveloop_loop4a:
124 btfsc enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (Screen dump)
125 bra diveloop_loop5
126 bra diveloop_loop6
127 diveloop_loop5:
128 btfss vusb_in ; USB (still) plugged in?
129 bcf enable_screen_dumps ; No, clear flag
130 call rs232_get_byte
131 btfsc rs232_recieve_overflow
132 bra diveloop_loop6
133 movlw "l"
134 cpfseq RCREG1
135 bra diveloop_loop6
136 call TFT_dump_screen ; Dump the screen contents
137 diveloop_loop6:
138
139 bra diveloop_loop ; Loop the divemode
140 ;--------------------------------------------------------------------------------------------------------
141
142
143
144
145
146
147 divemode_apnoe_tasks: ; 1 sec. Apnoe tasks
148 call TFT_display_apnoe_descent ; Show descent timer
149 call TFT_max_pressure ; use normal max. depth
150
151 btfsc divemode2 ; Time running?
152 bra divemode_apnoe_tasks2 ; New descent, reset data if flag is set
153
154 rcall apnoe_calc_maxdepth
155 call TFT_display_apnoe_surface
156 call TFT_display_apnoe_last_max ; Show last max. depth
157 incf apnoe_surface_secs,F
158 movlw d'60'
159 cpfseq apnoe_surface_secs
160 bra divemode_apnoe_tasks1
161 clrf apnoe_surface_secs
162 incf apnoe_surface_mins,F
163
164 divemode_apnoe_tasks1:
165 bcf FLAG_active_descent ; Clear flag
166 btfsc divemode2 ; Time running?
167 return ; Yes, return
168 bsf FLAG_active_descent ; Set Flag
169 return
170
171 divemode_apnoe_tasks2:
172 btfss FLAG_active_descent ; Are we descending?
173 return ; No, We are at the surface
174 rcall apnoe_calc_maxdepth ; Yes!
175 call TFT_apnoe_clear_surface ; Clear Surface timer
176 clrf apnoe_timeout_counter ; Delete timeout
177 clrf apnoe_surface_secs
178 clrf apnoe_surface_mins
179 clrf apnoe_secs
180 clrf apnoe_mins ; Reset Descent time
181 movlw .0
182 movff WREG,max_pressure+0
183 movff WREG,max_pressure+1 ; Reset Max. Depth
184 bcf FLAG_active_descent ; Clear flag
185 return
186
187 global apnoe_calc_maxdepth
188 apnoe_calc_maxdepth:
189 movff apnoe_max_pressure+0,sub_a+0
190 movff apnoe_max_pressure+1,sub_a+1
191 movff max_pressure+0,sub_b+0
192 movff max_pressure+1,sub_b+1
193 call subU16 ; sub_c = sub_a - sub_b
194 ; apnoe_max_pressure<max_pressure -> neg_flag=1
195 ; max_pressure<=apnoe_max_pressure -> neg_flag=0
196 btfss neg_flag
197 return
198 ;apnoe_max_pressure<max_pressure
199 movff max_pressure+0,apnoe_max_pressure+0
200 movff max_pressure+1,apnoe_max_pressure+1
201 return
202
203
204 calc_deko_divemode:
205 btfsc twosecupdate ; two seconds after the last call
206 bra calc_deko_divemode2 ; Yes, calculate and display deco data ("first second")
207
208 bsf twosecupdate ; No, but next second!
209 ; Routines used in the "other second"
210 call calc_average_depth ; calculate average depth
211 call calc_velocity ; calculate vertical velocity and display if > threshold (every two seconds)
212 call divemode_check_for_warnings ; Check for any warnings
213 call TFT_debug_output
214
215 btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode
216 return
217 btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode
218 return
219
220 ; Calculate CNS
221 rcall set_actual_ppo2 ; Set char_I_actual_ppO2
222 clrf WREG
223 movff WREG,char_I_step_is_1min ; Make sure to be in 2sec mode.
224 call deco_calc_CNS_fraction ; calculate CNS
225 movlb b'00000001' ; rambank 1 selected
226
227 ; Check for a gas change
228 rcall check_gas_change ; Checks if a better gas should be selected (by user)
229
230 return
231
232 global set_actual_ppo2
233 set_actual_ppo2: ; calculate ppO2 in 0.01bar (e.g. 150 = 1.50 bar ppO2)
234 SAFE_2BYTE_COPY amb_pressure, xA ; P_amb in millibar (1000 = 1.00 bar).
235 movlw d'10'
236 movwf xB+0
237 clrf xB+1
238 call div16x16 ; xC=p_amb/10 (100 = 1.00 bar).
239 movff xC+0,xA+0
240 movff xC+1,xA+1
241 movff char_I_O2_ratio,xB+0
242 clrf xB+1
243 call mult16x16 ; char_I_O2_ratio * (p_amb/10)
244 movff xC+0,xA+0
245 movff xC+1,xA+1
246 movlw d'100'
247 movwf xB+0
248 clrf xB+1
249 call div16x16 ; xC=(char_I_O2_ratio * p_amb/10)/100
250
251 ; Copy ppO2 for CNS calculation
252 tstfsz xC+1 ; Is ppO2 > 2.55bar ?
253 setf xC+0 ; yes: bound to 2.55... better than wrap around.
254
255 movff xC+0, char_I_actual_ppO2 ; copy last ppO2 to buffer register
256 btfsc is_bailout ; In Bailout?
257 return ; Yes, done.
258 ; No Bailout, check for ccr mode
259 btfsc FLAG_ccr_mode ; If FLAG_ccr_mode=1...
260 movff char_I_const_ppO2, char_I_actual_ppO2 ; ...copy last ppO2 to buffer register
261 return
262
263
264 calc_deko_divemode2:
265 bcf twosecupdate
266
267 btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode
268 return
269 btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode
270 return
271
272 extern deco_setup_dive
273 call deco_setup_dive ; Pass all parameters to the C code
274
275 TSTOSS opt_ccr_mode ; =0: Fixed SP, =1: Sensor
276 bra calc_deko_divemode2a
277 rcall divemode_setup_sensor_values ; Setup sensor values
278
279 calc_deko_divemode2a:
280 SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; C-code needs the ambient pressure
281 clrf WREG
282 movff WREG,char_I_step_is_1min ; Force 2 second deco mode
283
284 clrf TMR5L
285 clrf TMR5H ; 30,51757813µs/bit in TMR5L:TMR5H
286 call deco_calc_hauptroutine ; calc_tissue
287 movlb .1
288
289 movff char_O_deco_status,WREG ; Is a compute cycle finished ?
290 iorwf WREG,F
291 btfss STATUS,Z
292 return ; Return is status <> 0
293
294 ; Check if deco stops are necessary ?
295 movff char_O_first_deco_depth,wait_temp ; copy ceiling to temp register
296 tstfsz wait_temp ; Ceiling<0m?
297 bra calc_deko_divemode3 ; Yes!
298
299 btfsc decostop_active ; Already in nodeco mode ?
300 call TFT_display_ndl_mask ; No, Clear deco data, display nostop time
301 bcf decostop_active ; clear flag (again)
302
303 ; Copy for profile recording
304 clrf decodata+0
305 movff char_O_nullzeit,decodata+1 ; NDL
306
307 call TFT_display_ndl ; display no deco limit
308 return
309
310 calc_deko_divemode3:
311 btfss decostop_active ; Already in deco mode ?
312 call TFT_display_deko_mask ; No, clear nostop time, display decodata
313 bsf decostop_active ; Set flag (again)
314
315 ; Copy for profile recording
316 movff char_O_first_deco_depth,decodata+0 ; ceiling
317 movff char_O_first_deco_time,decodata+1 ; length of first stop in minues
318 call TFT_display_deko ; display decodata
319 call TFT_show_TTS_divemode ; display TTS
320
321 movff char_I_extra_time,WREG
322 tstfsz WREG ; extra time = 0?
323 bra calc_deko_divemode4 ; No, compute it
324 return
325
326 calc_deko_divemode4:
327 ; Check if extra cycles are needed to compute @5 variant:
328 decfsz apnoe_mins,F ; Reached count-down ?
329 return ; No: don't compute yet.
330
331 movlw .6
332 movff WREG,char_O_deco_status ; Stole next cycles for @5 variant.
333
334 movlw .2 ; Restart countdown.
335 movwf apnoe_mins
336 return ; done.
337
338 ;-----------------------------------------------------------------------------
339
340 divemodemode_togglegf: ; Toggle aGF/GF
341 bcf toggle_gf ; clear flag
342 btg use_agf ; Toggle GF
343 call TFT_gf_mask ; Setup Mask
344 clrf WREG
345 movff WREG,char_O_deco_status ; Restart decoplan computation
346 return
347
348 divemode_setup_sensor_values:
349 ; sum up sensor values (in xA:2) and active sensors in (xB:2)
350 clrf xB+0
351 clrf xB+1
352 clrf xA+0
353 clrf xA+1
354 btfss hud_status_byte,3 ; Sensor1 active?
355 bra divemode_setup_sensor_values2 ; No
356 movf o2_ppo2_sensor1,W
357 addwf xA+0
358 movlw .0
359 addwfc xA+1 ; Add into xA:2
360 incf xB+0,F ; Add a sensor
361 divemode_setup_sensor_values2:
362 btfss hud_status_byte,4 ; Sensor2 active?
363 bra divemode_setup_sensor_values3 ; No
364 movf o2_ppo2_sensor2,W
365 addwf xA+0
366 movlw .0
367 addwfc xA+1 ; Add into xA:2
368 incf xB+0,F ; Add a sensor
369 divemode_setup_sensor_values3:
370 btfss hud_status_byte,5 ; Sensor3 active?
371 bra divemode_setup_sensor_values4 ; No
372 movf o2_ppo2_sensor3,W
373 addwf xA+0
374 movlw .0
375 addwfc xA+1 ; Add into xA:2
376 incf xB+0,F ; Add a sensor
377 divemode_setup_sensor_values4:
378 call div16x16 ; xA/xB=xC with xA+0 as remainder
379 movff xC+0,sensor_setpoint ; Copy result
380 movff sensor_setpoint,char_I_const_ppO2 ; use sensor ppO2
381 return
382
383 calc_velocity: ; called every two seconds
384 btfss divemode
385 bra do_not_display_velocity ; display velocity only in divemode (Not at the surface after dive)
386
387 calc_velocity2:
388 SAFE_2BYTE_COPY amb_pressure, sub_a
389 movff last_pressure_velocity+0,sub_b+0
390 movff last_pressure_velocity+1,sub_b+1
391 movff sub_a+0,last_pressure_velocity+0 ; store old value for velocity
392 movff sub_a+1,last_pressure_velocity+1
393
394 call subU16 ; sub_c = amb_pressure - last_pressure
395
396 movff sub_c+0,xA+0
397 movff sub_c+1,xA+1
398 movlw d'39' ; 77 when called every second....
399 movwf xB+0
400 clrf xB+1
401 call mult16x16 ; differential pressure in mbar*77...
402 movff xC+0,divA+0
403 movff xC+1,divA+1
404 movlw d'7'
405 movwf divB+0
406 call div16 ; devided by 2^7 equals velocity in m/min
407
408 movlw d'99'
409 cpfsgt divA+0 ; limit to 99m/min
410 bra calc_velocity3
411 movwf divA+0 ; divA=99
412
413 calc_velocity3:
414 movlw velocity_warning_level_1 ; lowest threshold for display vertical velocity
415 subwf divA+0,W ;
416 btfss STATUS,C
417 bra do_not_display_velocity
418
419 bsf display_velocity
420 call TFT_display_velocity ; With divA+0 = m/min...
421 return
422
423 do_not_display_velocity:
424 btfss display_velocity ; Velocity was not displayed, do not delete
425 return
426 bcf display_velocity ; Velocity was displayed, delete velocity now
427 call TFT_display_velocity_clear
428 return
429
430 ;=============================================================================
431
432 timeout_menuview:
433 decfsz timeout_counter3,F ; timeout for menuview
434 return ; No timeout, return
435 ; Timeout, clear e.g. "Menu?"
436 goto menuview_toggle_reset ; "returns"
437
438 timeout_divemode_menu:
439 decfsz timeout_counter3,F ; timeout for divemode menu
440 return
441
442 global timeout_divemode_menu2
443 timeout_divemode_menu2: ; Called from divemenu_tree.asm
444 bcf divemode_menu ; Timeout! Clear flag
445 call TFT_clear_divemode_menu ; Clear menu
446 call TFT_active_gas_divemode ; Redraw gas/setpoint/diluent
447 bcf blinking_better_gas ; Clear flag to have temperature updated once
448 call TFT_temp_divemode ; Displays temperature
449
450 btfss decostop_active ; In deco mode ?
451 bra timeout_divemode_menu_ndl ; No, show NDL again
452 ; Show deco
453 call TFT_display_deko_mask ; clear nostop time, display decodata
454 call TFT_display_deko
455 call TFT_show_TTS_divemode
456 return
457 timeout_divemode_menu_ndl: ; Show NDL
458 call TFT_display_ndl_mask ; Clear deco data, display nostop time
459 call TFT_display_ndl
460 return
461
462 timeout_divemode:
463 btfsc divemode_menu ; Divemode menu active?
464 rcall timeout_divemode_menu ; Yes, check the timeout for it...
465
466 btfsc menuview ; is a menuview shown?
467 rcall timeout_menuview ; Yes, check the timeout for it...
468
469 btfss realdive ; Dive longer then one minute
470 return
471
472 btfsc FLAG_apnoe_mode ; In Apnoe mode?
473 bra timeout_divemode2 ; Yes, use CF30 [min] for timeout
474
475 ifndef __DEBUG
476 btfsc simulatormode_active ; In Simulator mode?
477 bra timeout_divemode3 ; Yes, use simulator timeout
478 endif
479
480 bcf divemode
481 incf timeout_counter,F
482 movlw d'0'
483 addwfc timeout_counter2,F ; timeout is 15bits
484
485 movlw LOW divemode_timeout
486 movwf sub_a+0
487 movlw HIGH divemode_timeout
488 movwf sub_a+1
489
490 movff timeout_counter, sub_b+0
491 movff timeout_counter2, sub_b+1
492 call subU16 ; sub_c = sub_a - sub_b
493 btfss neg_flag ; Result negative?
494 bsf divemode ; No, set flag
495 return
496
497 timeout_divemode2:
498 incf timeout_counter,F ; seconds...
499 movlw d'60'
500 cpfseq timeout_counter ; timeout_counter=60?
501 return ; No.
502 ; One minute timeout done.
503 clrf timeout_counter
504 bcf divemode
505 incf apnoe_timeout_counter,F
506 movlw apnoe_timeout ; apnoe timeout [min]
507 cpfseq apnoe_timeout_counter
508 bsf divemode
509 return
510
511 timeout_divemode3:
512 bcf divemode
513 incf timeout_counter,F
514 movlw simulator_timeout ; simulator timeout
515 cpfsgt timeout_counter
516 bsf divemode
517 return
518
519 update_temp_and_or_depth: ; New sensor data arrived...
520 btfsc temp_changed
521 call TFT_temp_divemode ; Displays temperature
522
523 btfsc pressure_refresh
524 call TFT_depth ; Displays new depth
525
526 rcall set_max_depth ; update max. depth if required
527 bcf pressure_refresh ; until new pressure is available
528 return
529
530 update_divemode60: ; update any minute
531 call get_battery_voltage ; gets battery voltage
532 call set_powersafe ; Battery low?
533 call TFT_max_pressure ; Update max. depth
534 call customview_minute ; Do every-minute tasks for the custom view area
535 bcf oneminupdate
536
537 btfss simulatormode_active ; in simulator mode?
538 return ; No
539 ; Yes, quite dive mode simulation after 21*256s=89min:36s
540 movlw .20
541 cpfsgt total_divetime_seconds+1 ; Timeout?
542 return ; No
543 ifdef __DEBUG
544 return ; No simulator timeout in debug mode
545 endif
546 bra divemode_option1 ; Yes, set to 0m and "return"
547
548 set_max_depth:
549 movff max_pressure+0,sub_a+0
550 movff max_pressure+1,sub_a+1
551 SAFE_2BYTE_COPY rel_pressure, sub_b
552 call subU16 ; sub_c = sub_a - sub_b
553 ; max_pressure<rel_pressure -> neg_flag=1
554 ; rel_pressure<=max_pressure -> neg_flag=0
555 btfss neg_flag
556 return
557 ; max_pressure<rel_pressure
558 movff sub_b+0,max_pressure+0
559 movff sub_b+1,max_pressure+1
560 call TFT_max_pressure ; No, use normal max. depth
561 return
562
563 set_min_temp:
564 movff minimum_temperature+0,sub_a+0
565 movff minimum_temperature+1,sub_a+1
566 SAFE_2BYTE_COPY temperature,sub_b
567 call sub16 ; sub_c = sub_a - sub_b
568 ; minimum_temperature<T -> neg_flag=1
569 ; T<=minimum_temperature -> neg_flag=0
570 btfsc neg_flag
571 return
572 ; minimum_temperature>=T
573 movff sub_b+0,minimum_temperature+0
574 movff sub_b+1,minimum_temperature+1
575 return
576
577 global set_dive_modes
578 set_dive_modes:
579 btfsc high_altitude_mode ; In high altitude (Fly) mode?
580 bra set_dive_modes3 ; Yes!
581
582 set_dive_modes0:
583 movlw LOW start_dive_threshold
584 movwf sub_a+0 ; dive_treshold is in cm
585 movlw HIGH start_dive_threshold
586 movwf sub_a+1 ; dive_treshold is in cm
587
588 set_dive_modes1:
589 SAFE_2BYTE_COPY rel_pressure, sub_b
590 call subU16 ; sub_c = sub_a - sub_b
591
592 btfss neg_flag
593 bra set_dive_modes2 ; too shallow (rel_pressure<dive_threshold)
594
595 btfsc realdive ; Dive longer than one minute?
596 clrf timeout_counter ; Yes, reset timout counter
597
598 set_dive_modes_common:
599 bsf divemode ; (Re-)Set divemode flag
600 bsf divemode2 ; displayed divetime is running
601 return
602
603 set_dive_modes2:
604 bcf divemode2 ; Stop time
605 btfss realdive ; dive longer then one minute?
606 bcf divemode ; no -> this was no real dive
607 return ; No, return
608
609
610 set_dive_modes3: ; High-altitude mode
611 btfsc realdive ; dive longer then one minute?
612 bra set_dive_modes0 ; Yes -> this is a real dive -> Use start_dive_threshold or ascend
613
614 movlw HIGH high_altitude_dive_threshold
615 movwf sub_a+1
616 movlw LOW high_altitude_dive_threshold
617 movwf sub_a+0
618 bra set_dive_modes1
619
620 set_powersafe:
621 movlw color_code_battery_low+1; [%]
622 cpfslt batt_percent
623 return
624
625 movlw d'7' ; Type of Alarm (Battery Low)
626 movwf AlarmType ; Copy to Alarm Register
627 bsf event_occured ; Set Event Flag
628 movlw .0
629 movff WREG,opt_brightness ; Set Brightness to ECO
630 return ; return
631
632 calc_average_depth:
633 btfsc reset_average_depth ; Reset the Avewrage depth?
634 rcall reset_average1 ; Reset the resettable average depth
635
636 ; 1. Add new 2xdepth to the Sum of depths registers
637 SAFE_2BYTE_COPY rel_pressure, xB ; Buffer...
638 bcf STATUS,C
639 rlcf xB+0,F
640 rlcf xB+1,F ; x2
641
642 movf xB+0,w
643 addwf average_depth_hold+0,F
644 movf xB+1,w
645 addwfc average_depth_hold+1,F
646 movlw d'0'
647 addwfc average_depth_hold+2,F
648 addwfc average_depth_hold+3,F ; Will work up to 9999mbar*60*60*24=863913600mbar
649
650 ; Do the same for the _total registers (Non-Resettable)
651 movf xB+0,w
652 addwf average_depth_hold_total+0,F
653 movf xB+1,w
654 addwfc average_depth_hold_total+1,F
655 movlw d'0'
656 addwfc average_depth_hold_total+2,F
657 addwfc average_depth_hold_total+3,F ; Will work up to 9999mbar*60*60*24=863913600mbar
658
659 ; 2. Compute Average Depth on base of average_divesecs:2
660 movff average_divesecs+0,xB+0
661 movff average_divesecs+1,xB+1 ; Copy
662 movff average_depth_hold+0,xC+0
663 movff average_depth_hold+1,xC+1
664 movff average_depth_hold+2,xC+2
665 movff average_depth_hold+3,xC+3
666
667 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
668 movff xC+0,avr_rel_pressure+0
669 movff xC+1,avr_rel_pressure+1
670
671 ; 3. Compute Total Average Depth on base of total_divetime_seconds:2
672 movff total_divetime_seconds+0,xB+0
673 movff total_divetime_seconds+1,xB+1 ; Copy
674 movff average_depth_hold_total+0,xC+0
675 movff average_depth_hold_total+1,xC+1
676 movff average_depth_hold_total+2,xC+2
677 movff average_depth_hold_total+3,xC+3
678 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
679 movff xC+0,avr_rel_pressure_total+0
680 movff xC+1,avr_rel_pressure_total+1
681
682 ; ; Compute Total Average Depth on base of divemins:2 and divesecs
683 ; movff divemins+0,xA+0
684 ; movff divemins+1,xA+1
685 ; movlw d'60'
686 ; movwf xB+0
687 ; clrf xB+1
688 ; call mult16x16 ; xC:4=xA:2*xB:2
689 ; movf divesecs,W
690 ; addwf xC+0,F
691 ; movlw d'0'
692 ; addwfc xC+1,F ; xC:2 holds total dive seconds
693 ; movlw d'3' ; 2+1
694 ; btfss divesecs,0 ; divesecs even?
695 ; movlw d'2' ; Yes, do not add +1
696 ; addwf xC+0,F
697 ; movlw d'0'
698 ; addwfc xC+1,F
699 ; ; Ignore xC+2 and xC+3. Total Average will only work up to divetime=1092:16
700 ; movff xC+0,xB+0
701 ; movff xC+1,xB+1 ; Copy
702 ; movff average_depth_hold_total+0,xC+0
703 ; movff average_depth_hold_total+1,xC+1
704 ; movff average_depth_hold_total+2,xC+2
705 ; movff average_depth_hold_total+3,xC+3
706 ;
707 ; call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
708 ; movff xC+0,avr_rel_pressure_total+0
709 ; movff xC+1,avr_rel_pressure_total+1
710
711 return
712
713 reset_average1:
714 clrf average_depth_hold+0
715 clrf average_depth_hold+1
716 clrf average_depth_hold+2
717 clrf average_depth_hold+3 ; Clear average depth register
718 movlw d'2'
719 movwf average_divesecs+0
720 clrf average_divesecs+1
721 bcf reset_average_depth ; Clear flag
722 return
723
724 test_switches_divemode: ; checks switches in divemode
725 btfsc divemode_menu ; Divemode menu shown?
726 bra test_switches_divemode_menu ; Yes, use menu processor
727 btfsc switch_left
728 bra test_switches_divemode2 ; Enter button pressed, check if we need to do something
729 btfss switch_right
730 return ; No button press
731 tstfsz menupos2 ; any option shown?
732 bra test_switches_divemode1 ; Yes, do option tasks
733 bsf toggle_customview ; No, toggle custom view
734 return
735
736 test_switches_divemode_menu:
737 btfsc switch_left
738 bra test_switches_divemode_menu2 ; Move cursor
739 btfsc switch_right
740 bra test_switches_divemode_menu3 ; Enter submenu or do something
741 return ; No button press
742
743 test_switches_divemode_menu1:
744 clrf menupos
745 test_switches_divemode_menu2:
746 incf menupos,F
747 incf menupos4,W ; menupos4+1 -> WREG
748 cpfslt menupos ; >menupos4 (Set in menu_processor.asm)?
749 bra test_switches_divemode_menu1; > Yes, set to 1
750 call TFT_divemode_menu_cursor ; Update the cursor
751 bcf switch_left
752 movlw divemode_menu_timeout ; Reload timeout
753 movwf timeout_counter3 ; timeout for divemode menu
754 return
755
756 test_switches_divemode_menu3: ; Enter submenu or do something
757 bcf switch_right
758 ; decf menupos,F ; menu_processor needs 0-5...
759 extern do_line_menu
760 goto do_line_menu ; Warning! Trashes STKPTR and returns to diveloop_loop4:
761
762 test_switches_divemode1:
763 bcf switch_right
764 movlw divemode_menuview_timeout
765 movwf timeout_counter3 ; Reload timeout
766 movff menupos2,WREG ; Menupos3 holds number of customview/divemode menu function
767 dcfsnz WREG,F
768 bra divemode_option0 ; Start/Setup Divemode menu
769 dcfsnz WREG,F
770 bra divemode_option1 ; Quit Simulation?
771 dcfsnz WREG,F
772 bra divemode_option2 ; Descent 1m
773 dcfsnz WREG,F
774 bra divemode_option3 ; Ascend 1m
775 dcfsnz WREG,F
776 bra divemode_option4 ; Quit Apnoe mode
777 dcfsnz WREG,F
778 bra divemode_option5 ; Reset Stopwatch (In Gauge mode)
779 return
780
781 test_switches_divemode2:
782 bcf switch_left
783 call menuview_toggle ; Menu or Simulator tasks
784 return
785
786 gas_switched_common:
787 decf menupos,W ; 1-5 -> 0-4
788 btfss FLAG_ccr_mode ; Choose OC Gases
789 rcall setup_gas_registers ; With WREG=Gas 0-4
790 btfsc FLAG_ccr_mode ; Choose CC Diluents
791 rcall setup_dil_registers ; With WREG=Gas 0-4
792
793 decf menupos,W ; 1-5 -> 0-4
794 btfsc is_bailout ; Choose OC Bailouts (OC Gases)
795 rcall setup_gas_registers ; With WREG=Gas 0-4
796
797 call TFT_active_gas_divemode ; Display gas/Setpoint
798 bsf event_occured ; Set global event byte
799 bsf stored_gas_changed ; Set Flag for profile
800 bcf divemode_gaschange ; Clear flag
801 clrf WREG
802 movff WREG,char_O_deco_status ; Restart decoplan computation
803 return
804
805 global setup_gas_registers
806 setup_gas_registers: ; With WREG=Gas 0-4
807 lfsr FSR1,opt_gas_O2_ratio+0
808 movff PLUSW1,char_I_O2_ratio ; O2 (For ppO2 calculations)
809 lfsr FSR1,opt_gas_He_ratio+0
810 movff PLUSW1,char_I_He_ratio ; He
811 incf WREG,W ; Gas# 1-5
812 movff WREG,char_I_current_gas ; Set gas
813 movff WREG,active_gas ; Set for logbook and display
814 banksel char_I_O2_ratio
815 movf char_I_O2_ratio,W ; Add O2...
816 addwf char_I_He_ratio,W ; ...and He...
817 sublw .100 ; ...subtract both from 100
818 movwf char_I_N2_ratio ; -> N2!
819 banksel common
820 return
821
822 global setup_dil_registers
823 setup_dil_registers: ; With WREG=dil 0-4
824 lfsr FSR1,opt_dil_O2_ratio+0
825 movff PLUSW1,char_I_O2_ratio ; O2 (For ppO2 calculations)
826 lfsr FSR1,opt_dil_He_ratio+0
827 movff PLUSW1,char_I_He_ratio ; He
828 incf WREG,W ; Gas# 1-5
829 movff WREG,char_I_current_gas ; Set gas
830 movff WREG,active_gas ; Set for logbook and display
831 banksel char_I_O2_ratio
832 movf char_I_O2_ratio,W ; Add O2...
833 addwf char_I_He_ratio,W ; ...and He...
834 sublw .100 ; ...subtract both from 100
835 movwf char_I_N2_ratio ; -> N2!
836 banksel common
837 return
838
839 divemode_option0: ; Start/Setup Divemode menu
840 call TFT_clear_divemode_menu ; Clear menu area
841 bcf menuview
842 extern do_main_divemenu
843 call do_main_divemenu
844 global divemode_option0_return
845 divemode_option0_return:
846 ; movlw .1
847 ; movwf menupos ; Set to first option in divemode menu
848 call TFT_divemode_menu_cursor; Show the cursor
849 movlw divemode_menu_timeout
850 movwf timeout_counter3 ; timeout for divemode menu
851 bsf divemode_menu ; Set flag
852 clrf menupos2 ; Clear option counter
853 bra diveloop_loop4 ; Goto back to diveloop (Menuprocessor trashes STKPTR!)
854
855 divemode_option4:
856 movlw d'58' ; two seconds left
857 movwf timeout_counter
858 movlw apnoe_timeout-1 ; apnoe timeout [min]
859 movwf apnoe_timeout_counter
860 btfss simulatormode_active ; in simulator mode?
861 return ; No
862 divemode_option1: ; Quit simulation mode
863 banksel isr_backup
864 movlw low .1000
865 movwf sim_pressure+0
866 movlw high .1000
867 movwf sim_pressure+1 ; Set to 0m -> End of Dive
868 banksel common
869 call menuview_toggle_reset ; Reset to zero (Zero=no menuview)
870
871 btfss FLAG_apnoe_mode ; In Apnoe mode?
872 return ; No
873 movlw d'58' ; two seconds left
874 movwf timeout_counter
875 movlw apnoe_timeout-1 ; apnoe timeout [min]
876 movwf apnoe_timeout_counter
877 return
878
879 divemode_option3: ; minus 1m
880 banksel isr_backup
881 movlw d'100'
882 subwf sim_pressure+0
883 movlw .0
884 subwfb sim_pressure+1
885 rcall divemode_simulator_check_limits
886 banksel common
887 return
888
889 divemode_option2: ; plus 1m
890 banksel isr_backup
891 movlw d'100'
892 addwf sim_pressure+0
893 movlw .0
894 addwfc sim_pressure+1
895 rcall divemode_simulator_check_limits
896 banksel common
897 return
898
899 divemode_option5:
900 call menuview_toggle_reset ; Reset to zero (Zero=no menuview)
901 bsf reset_average_depth ; Set Flag
902 return
903
904 divemode_simulator_check_limits:
905 ; Check limits (150m and 0m)
906 movlw LOW d'16000' ; Compare to 16bar=16000mbar (150m).
907 subwf sim_pressure+0,W
908 movlw HIGH d'16000'
909 subwfb sim_pressure+1,W
910 bnc divemode_simulator_check_limits2 ; No-carry = borrow = not deeper
911
912 ; Too deep, limit to 150m
913 movlw LOW d'16000'
914 movwf sim_pressure+0
915 movlw HIGH d'16000'
916 movwf sim_pressure+1
917 return
918 divemode_simulator_check_limits2:
919 movlw LOW d'1000' ; Compare to 1bar == 0m == 1000 mbar.
920 subwf sim_pressure+0,W
921 movlw HIGH d'1000'
922 subwfb sim_pressure+1,W
923 btfsc STATUS,C ; No-carry = borrow = not deeper.
924 return ; Deeper than 0m == Ok.
925 ; Too shallow, limit to 0m
926 movlw LOW d'1000'
927 movwf sim_pressure+0
928 movlw HIGH d'1000'
929 movwf sim_pressure+1
930 return
931
932 ;=============================================================================
933 ; Compare all enabled gas in list, to see if a better one is available.
934 ;
935 ; Output: better_gas_available, better_gas_number
936 ;
937 check_gas_change: ; Checks if a better gas should be selected (by user)
938 bcf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode
939 clrf better_gas_number ; Clear better gas register
940
941 SAFE_2BYTE_COPY rel_pressure,xA
942 movlw d'100'
943 movwf xB+0
944 clrf xB+1
945 call div16x16 ; compute depth in full m -> result in xC+0
946
947 btfss FLAG_ccr_mode ; In CCR mode...
948 bra check_gas_change_OC_bail; No, check for OC or bailout
949 btfsc is_bailout ; Bailout?
950 bra check_gas_change_OC_bail; Yes, check for OC or bailout
951
952 ; Check Diluents
953 movlw .0
954 rcall check_dil_common ; With Gas 0-4 in WREG
955 movlw .1
956 rcall check_dil_common ; With Gas 0-4 in WREG
957 movlw .2
958 rcall check_dil_common ; With Gas 0-4 in WREG
959 movlw .3
960 rcall check_dil_common ; With Gas 0-4 in WREG
961 movlw .4
962 rcall check_dil_common ; With Gas 0-4 in WREG
963 bra check_gas_change_exit
964
965 check_gas_change_OC_bail:
966 movlw .0
967 rcall check_gas_common ; With Gas 0-4 in WREG
968 movlw .1
969 rcall check_gas_common ; With Gas 0-4 in WREG
970 movlw .2
971 rcall check_gas_common ; With Gas 0-4 in WREG
972 movlw .3
973 rcall check_gas_common ; With Gas 0-4 in WREG
974 movlw .4
975 rcall check_gas_common ; With Gas 0-4 in WREG
976 ; bra check_gas_change_exit
977 check_gas_change_exit:
978 btfss better_gas_available ; Is a better gas available
979 bcf blinking_better_gas ; No, Clear blinking flag
980 btfss better_gas_available ; Is a better gas available
981 clrf better_gas_number ; No, Clear better_gas_number (For gaslist display)
982 call TFT_active_gas_divemode ; Display gas/Setpoint
983 return
984
985 check_gas_common: ; With Gas 0-4 in WREG
986 btfsc better_gas_available ; Better Gas already found?
987 return ; Yes, return
988 lfsr FSR1,opt_gas_type ; 0=Disabled, 1=First, 2=Travel, 3=Deco
989 btfss PLUSW1,0 ; Test for Bit0 and 1 -> type=3 -> Deco
990 return ; No
991 btfss PLUSW1,1 ; Test for Bit0 and 1 -> type=3 -> Deco
992 return ; No
993 incf WREG,W ; 1-5
994 cpfseq active_gas ; is this gas currently selected?
995 bra check_gas_common2 ; No
996 return ; Yes, skip test for active gas
997 check_gas_common2:
998 decf WREG,W ; 0-4
999 movwf hi ; Save tested gas 0-4
1000 lfsr FSR1,char_I_deco_gas_change
1001 movff PLUSW1,lo ; Change depth into lo
1002 movlw minimum_change_depth
1003 cpfsgt lo ; Change depth>minimum_change_depth?
1004 return ; No, Change depth not deep enough, skip!
1005 movf xC+0,W ; load depth in m into WREG
1006 cpfsgt lo ; gas_change_depth < current depth?
1007 return ; No, check next gas
1008 incf hi,W ; 1-5
1009 movwf better_gas_number ; number (1-5) of the "better gas" in divemode, =0: no better gas available
1010 movlw better_gas_window
1011 subwf lo,W ; Change depth-better_gas_window
1012 cpfslt xC+0 ; current depth<Change depth-better_gas_window?
1013 bsf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode
1014 return
1015
1016 check_dil_common: ; With Dil 0-4 in WREG
1017 btfsc better_gas_available ; Better Diluent already found?
1018 return ; Yes, return
1019 lfsr FSR1,opt_dil_type ; 0=Disabled, 1=First, 2=Normal
1020 tstfsz PLUSW1 ; =0?
1021 bra check_dil_common1 ; No
1022 return ; Yes, skip inactive diluents for test
1023 check_dil_common1:
1024 incf WREG,W ; 1-5
1025 cpfseq active_gas ; is this diluent currently selected?
1026 bra check_dil_common2 ; No
1027 return ; Yes, skip test for active diluent
1028 check_dil_common2:
1029 decf WREG,W ; 0-4
1030 movwf hi ; Save tested diluent 0-4
1031 lfsr FSR1,char_I_dil_change
1032 movff PLUSW1,lo ; Change depth into lo
1033 movlw minimum_change_depth
1034 cpfsgt lo ; Change depth>minimum_change_depth?
1035 return ; No, Change depth not deep enough, skip!
1036 movf xC+0,W ; load depth in m into WREG
1037 cpfsgt lo ; gas_change_depth < current depth?
1038 return ; No, check next gas
1039 incf hi,W ; 1-5
1040 addlw .5 ; 6-10
1041 movwf better_gas_number ; number (1-5) of the "better gas" in divemode, =0: no better gas available
1042 movlw better_gas_window
1043 subwf lo,W ; Change depth-better_gas_window
1044 cpfslt xC+0 ; current depth<Change depth-better_gas_window?
1045 bsf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode
1046 return
1047
1048 ;=============================================================================
1049 ; Setup everything to enter divemode.
1050 ;
1051
1052 dive_boot_oc:
1053 extern get_first_gas_to_WREG
1054 call get_first_gas_to_WREG ; Gets first gas (0-4) into WREG
1055 movff WREG,char_I_first_gas ; Copy for compatibility
1056 movff WREG,active_gas ; Set for logbook and display
1057 rcall setup_gas_registers ; With WREG=Gas 0-4
1058 return
1059
1060 dive_boot_cc:
1061 rcall divemode_setup_sensor_values ; setup sensor values
1062 TSTOSS opt_ccr_mode ; =0: Fixed SP, =1: Sensor
1063 movff char_I_setpoint_cbar+0,char_I_const_ppO2 ; Setup fixed Setpoint (Always start with SP1)
1064 extern get_first_dil_to_WREG
1065 call get_first_dil_to_WREG ; Gets first gas (0-4) into WREG
1066 movff WREG,char_I_first_gas ; Copy for compatibility
1067 movff WREG,active_gas ; Set for logbook and display
1068 rcall setup_dil_registers ; With WREG=Gas 0-4
1069 return
1070
1071 diveloop_boot:
1072 call restart_set_modes_and_flags
1073
1074 call I2C_sleep_accelerometer ; Stop accelerometer
1075 call I2C_sleep_compass ; Stop compass
1076
1077 clrf WREG
1078 movff WREG,max_pressure+0 ; clear some variables
1079 movff WREG,max_pressure+1
1080
1081 bcf use_agf ; Start with normal GF set
1082 bcf divemode_menu ; clear divemode menu flag
1083 movlw d'1'
1084 movwf apnoe_max_pressure+0
1085 clrf apnoe_max_pressure+1
1086 clrf apnoe_surface_mins
1087 clrf apnoe_surface_secs
1088 clrf apnoe_mins
1089 clrf apnoe_secs
1090 clrf divemins+0
1091 clrf divemins+1
1092 bcf no_more_divesecs ; =1: Do no longer show seconds in divemode
1093 bcf divemode_menu_active
1094 clrf menupos
1095 clrf menupos3 ; Reset to zero (Zero=no custom view)
1096 clrf menupos2 ; Reset to zero (Zero=no premenu or simulator task)
1097
1098 bcf is_bailout ; =1: Bailout
1099 btfss FLAG_ccr_mode
1100 rcall dive_boot_oc
1101 btfsc FLAG_ccr_mode
1102 rcall dive_boot_cc
1103
1104 bcf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode
1105 clrf better_gas_number ; Clear better gas register
1106
1107 clrf samplesecs
1108 clrf apnoe_timeout_counter ; timeout in minutes
1109 clrf timeout_counter ; takes care of the timeout (Low byte)
1110 clrf timeout_counter2 ; takes care of the timeout (High byte)
1111 clrf AlarmType ; Clear all alarms
1112 bcf event_occured ; clear flag
1113 clrf total_divetime_seconds+1
1114 clrf average_depth_hold_total+0
1115 clrf average_depth_hold_total+1
1116 clrf average_depth_hold_total+2
1117 clrf average_depth_hold_total+3 ; Clear Non-Resettable Average
1118 rcall reset_average1 ; Reset the resettable average depth
1119 bcf decostop_active
1120 bcf better_gas_available ;=1: A better gas is available and a gas change is advised in divemode
1121 call ghostwriter_short_header ; Write short header with divenumber into profile memory
1122
1123 btfsc simulatormode_active
1124 bra diveloop_boot_1
1125 ; Normal mode = Surface pressure is the pressure 30mn before dive.
1126 SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface ;copy surfacepressure to deco routine
1127 SAFE_2BYTE_COPY last_surfpressure_30min, last_surfpressure ;copy surfacepressure to last_surfpressure for correct depth
1128 bra diveloop_boot_2
1129
1130 diveloop_boot_1:
1131 ; Simulator mode: Surface pressure is 1bar.
1132 movlw LOW .1000
1133 movff WREG,int_I_pres_surface+0 ; LOW copy surfacepressure to deco routine
1134 movlw HIGH .1000
1135 movff WREG,int_I_pres_surface+1 ; HIGH copy surfacepressure to deco routine
1136
1137 diveloop_boot_2:
1138 SAFE_2BYTE_COPY temperature,minimum_temperature ; Reset Min-Temp registers
1139
1140 ; Init profile recording parameters
1141 movlw samplingrate
1142 movwf samplesecs_value ; to avoid EEPROM access in the ISR
1143 movlw div_temperature
1144 movwf divisor_temperature ; load divisors for profile storage
1145 movlw div_deco
1146 movwf divisor_deco
1147 movlw div_gf
1148 movwf divisor_gf
1149 movlw div_ppo2_sensors
1150 movwf divisor_ppo2_sensors
1151 movlw div_decoplan
1152 movwf divisor_decoplan
1153 movlw div_cns
1154 movwf divisor_cns
1155 movlw div_tank
1156 movwf divisor_tank
1157
1158 btfss FLAG_apnoe_mode ; In Apnoe mode?
1159 bra divemode1
1160 ; Overwrite some parameters in Apnoe mode....
1161 movlw samplingrate_apnoe
1162 movwf samplesecs_value ; to avoid EEPROM access in the ISR
1163
1164 divemode1:
1165 bcf LEDg
1166 bcf LEDr
1167 bcf realdive
1168 btfss simulatormode_active ; do not disable in simulator mode!
1169 call disable_rs232 ; Disable RS232
1170 btfsc enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (Screen dump)
1171 call enable_rs232 ; Also sets to speed_normal ...
1172 movlw .2
1173 movwf total_divetime_seconds+0
1174 movwf divesecs ; Start at 2seconds
1175 bsf divemode2 ; displayed divetime is running (Divetime starts HERE)
1176
1177 movff int_O_CNS_fraction+0,CNS_start+0
1178 movff int_O_CNS_fraction+1,CNS_start+1 ; Save CNS value at beginning of dive
1179 movff char_O_relative_gradient_GF,GF_start ; Save GF value at beginning of dive
1180 return ; Done with divemode boot
1181
1182 divemode_check_for_warnings:
1183 btfss secs,1 ; Every four seconds
1184 return
1185
1186 movf warning_counter_backup,W
1187 cpfseq warning_counter ; warning_counter_backup = warning_counter?
1188 call TFT_clear_warning_text ; No, clear all warnings
1189 movff warning_counter,warning_counter_backup ; copy warning_counter
1190
1191 bcf warning_active ; Clear flag
1192 clrf warning_counter ; Clear counter
1193
1194 ; Warnings for all modes
1195 call check_warn_battery ; Check if the battery level should be displayed/warned
1196
1197 btfsc FLAG_apnoe_mode ; Done for Apnoe or Gauge mode
1198 bra divemode_check_for_warnings2
1199 btfsc FLAG_gauge_mode ; Done for Apnoe or Gauge mode
1200 bra divemode_check_for_warnings2
1201
1202 ; Warnings only in deco modes
1203 btfss FLAG_ccr_mode ; Don't check in CCR mode
1204 rcall check_ppO2 ; check ppO2 and displays warning, if required
1205 btfsc is_bailout ; But check in Bailout case...
1206 rcall check_ppO2 ; check ppO2 and displays warning, if required
1207 rcall check_cns_violation ; Check CNS value and display it, if required
1208 btfsc decostop_active ; In deco mode?
1209 rcall check_and_store_gf_violation ; Yes, Sets warnings, if required
1210 btfsc decostop_active ; In deco mode?
1211 call TFT_ftts ; Show @+x time
1212 btfsc use_agf ; In aGF mode?
1213 rcall warn_agf ; Yes, show a warning for it
1214
1215 divemode_check_for_warnings2:
1216 ; Display the warning icon?
1217 btfsc warning_active ; Any warning active?
1218 call TFT_divemode_warning ; Yes
1219 btfss warning_active ; Any warning active?
1220 call TFT_divemode_warning_clear ; No, clear warning icon
1221
1222 ; Setup warning_page number
1223 incf warning_page,F
1224 bcf STATUS,C
1225 rlcf warning_page,W ; *2
1226 cpfsgt warning_counter ; > warning_counter
1227 clrf warning_page ; No, clear
1228
1229 ; Clear 2nd row of warnings if there is nothing to show (on this page)
1230 btfss second_row_warning ; =1: The second row contains a warning
1231 call TFT_clear_warning_text_2nd_row ; No, clear this row
1232 return ; Done.
1233
1234 global check_warn_battery
1235 check_warn_battery:
1236 movff batt_percent,lo
1237 movlw battery_show_level+1
1238 cpfslt lo
1239 return ; No Display, no warning
1240 ; Display Battery, but warn?
1241 incf warning_counter,F ; increase counter
1242 call TFT_update_batt_percent_divemode ; Show percent
1243
1244 movlw color_code_battery_low+1
1245 cpfslt lo ;
1246 return ; No warning
1247 bsf warning_active ; Set Warning flag
1248 return
1249
1250 check_ppO2: ; check current ppO2 and display warning if required
1251 SAFE_2BYTE_COPY amb_pressure, xA
1252 movlw d'10'
1253 movwf xB+0
1254 clrf xB+1
1255 call div16x16 ; xC=p_amb/10
1256
1257 movff xC+0,xA+0
1258 movff xC+1,xA+1
1259 movff char_I_O2_ratio,xB+0 ; =O2 ratio
1260 clrf xB+1
1261 call mult16x16 ; char_I_O2_ratio * p_amb/10
1262
1263 ; Check very high ppO2 manually
1264 tstfsz xC+2 ; char_I_O2_ratio * p_amb/10 > 65536, ppO2>6,55bar?
1265 bra check_ppO2_1 ; Yes, display Value!
1266 ; Check if ppO2>3,30bar
1267 btfsc xC+1,7
1268 bra check_ppO2_1 ; Yes!
1269
1270 ; Check for low ppo2
1271 movff xC+0,sub_b+0
1272 movff xC+1,sub_b+1
1273 movff opt_ppO2_min,WREG
1274 mullw d'100' ; opt_ppO2_min*100
1275 movff PRODL,sub_a+0
1276 movff PRODH,sub_a+1
1277 call subU16
1278 btfsc neg_flag
1279 bra check_ppO2_0 ; Not too low
1280 ; ppO2 low
1281 incf warning_counter,F ; increase counter
1282 call TFT_display_ppo2 ; Show ppO2
1283 movlw d'4' ; Type of Alarm (ppO2 low)
1284 movwf AlarmType ; Copy to Alarm Register
1285 bsf event_occured ; Set Event Flag
1286 bsf warning_active ; Set Warning flag
1287 return ; Done.
1288
1289 check_ppO2_0:
1290 ; Check if ppO2 should be displayed
1291 movlw ppo2_display_high
1292 mullw d'100' ; ppo2_display_high*100
1293 movff PRODL,sub_a+0
1294 movff PRODH,sub_a+1
1295 call subU16
1296 btfss neg_flag
1297 return ; No Display, no warning
1298 ; Display ppO2, but warn?
1299 incf warning_counter,F ; increase counter
1300 call TFT_display_ppo2 ; Show ppO2
1301
1302 ;check if we are within our warning thresholds!
1303 movff xC+0,sub_b+0
1304 movff xC+1,sub_b+1
1305 movff opt_ppO2_max,WREG ; PPO2 Max for MOD calculation and color coding in divemode
1306 mullw d'100' ; opt_ppO2_max*100
1307 movff PRODL,sub_a+0
1308 movff PRODH,sub_a+1
1309 call subU16
1310 btfss neg_flag
1311 return ; Done. Not too high
1312 movlw d'5' ; Type of Alarm (ppO2 high)
1313 movwf AlarmType ; Copy to Alarm Register
1314 bsf event_occured ; Set Event Flag
1315 bsf warning_active ; Set Warning flag
1316 return ; Done.
1317
1318 check_ppO2_1: ; ppO2 very high
1319 incf warning_counter,F ; increase counter
1320 call TFT_display_ppo2 ; Show ppO2
1321 movlw d'5' ; Type of Alarm
1322 movwf AlarmType ; Copy to Alarm Register
1323 bsf event_occured ; Set Event Flag
1324 bsf warning_active ; Set Warning flag
1325 return ; Done.
1326
1327 global check_cns_violation
1328 check_cns_violation:
1329 ; Check if CNS should be displayed
1330 movff int_O_CNS_fraction+1,lo ; copy into bank1
1331 tstfsz lo ; >255% ?
1332 bra check_cns_violation2 ; Yes
1333 movff int_O_CNS_fraction+0,lo ; copy into bank1
1334
1335 movlw cns_warning_high ; cns_warning_high
1336 subwf lo,W
1337 btfsc STATUS,C
1338 bsf warning_active ; Set Warning flag
1339
1340 movlw cns_display_high ; cns_display_high
1341 subwf lo,W
1342 btfss STATUS,C
1343 return ; No Display, no warning
1344 ; Display CNS
1345 incf warning_counter,F ; increase counter
1346 call TFT_display_cns ; Show CNS
1347 return
1348
1349 check_cns_violation2:
1350 incf warning_counter,F ; increase counter
1351 call TFT_display_cns ; Show CNS
1352 bsf warning_active ; Set Warning flag
1353 return
1354
1355 global check_and_store_gf_violation
1356 check_and_store_gf_violation:
1357 movff char_O_gradient_factor,lo ; gradient factor absolute (Non-GF model)
1358 movff char_I_deco_model,hi
1359 decfsz hi,F ; jump over next line if char_I_deco_model == 1
1360 movff char_O_relative_gradient_GF,lo ; gradient factor relative (GF model)
1361
1362 movlw gf_warning_high
1363 cpfsgt lo
1364 bra check_and_store_gf_violation2 ; No warning
1365 movlw d'2' ; Type of Alarm
1366 movwf AlarmType ; Copy to Alarm Register
1367 bsf event_occured ; Set Event Flag
1368 bsf warning_active ; Set Warning flag
1369 check_and_store_gf_violation2:
1370 movlw gf_display_high
1371 cpfsgt lo
1372 return ; No Display, no warning
1373 ; Display GF
1374 incf warning_counter,F ; increase counter
1375 call TFT_warning_gf ; Show GF Warning
1376 return
1377
1378 warn_agf:
1379 incf warning_counter,F ; increase counter
1380 call TFT_warning_agf ; Show aGF warning
1381 bsf warning_active ; Set Warning flag
1382 return
1383
1384
1385 END