changeset 656:8af5aefbcdaf default tip

Update to 3.31 beta
author heinrichsweikamp
date Thu, 27 Nov 2025 18:32:58 +0100
parents c7b7b8a358cd
children
files src/aa_wordprocessor.asm src/adc_lightsensor.asm src/adc_lightsensor.inc src/calibrate.asm src/calibrate.inc src/clib.lib src/color_processor.asm src/comm.asm src/compass_ops.asm src/configuration.inc src/customview.asm src/divemenu_tree.asm src/divemode.asm src/divemode.inc src/eeprom_rs232.asm src/eeprom_rs232.inc src/ghostwriter.asm src/hwos.asm src/hwos.inc src/i2c.asm src/i2c.inc src/isr.asm src/menu_processor.asm src/menu_tree.asm src/ms5541.asm src/option_table.asm src/options.asm src/p2_deco.c src/ports.inc src/shared_definitions.h src/simulator.asm src/sleepmode.asm src/start.asm src/surfmode.asm src/text_english.inc src/text_french.inc src/text_german.inc src/text_italian.inc src/text_multilang.asm src/tft.asm src/tft_outputs.asm src/tft_outputs.inc
diffstat 42 files changed, 1905 insertions(+), 1758 deletions(-) [+]
line wrap: on
line diff
--- a/src/aa_wordprocessor.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/aa_wordprocessor.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -491,7 +491,51 @@
 	bra		aa_decode_1				;       NO  - loop
 	return							;       YES - done
 
+;------------------------------------------------------------------------------
+; Convert the output buffer to all caps, leave anything outside "a" to "z" untouched
+; Input    buffer (NEEDS TO BE NULL TERMINATED)
+; Output   buffer
+; Trashed  PROD
 
+all_caps:
+    	lfsr	FSR2, buffer			; FSR2 pointer to start of string
+
+all_caps_1:
+	movf	POSTINC2,W			; get character
+	bz	all_caps_3			; exit if null byte encountered
+	movwf	PRODL
+
+	btfsc	force_all_caps
+	bra	all_caps_2
+	movlw	.58
+	cpfslt	PRODL
+	bra	all_caps_2			; >57, can't be a "0" to "9", continue
+
+	movlw	.47
+	cpfsgt	PRODL
+	bra	all_caps_2			; <48, can't be a "0" to "9", continue
+	bra	all_caps_3			; "0" to "9" found, exit here
+	
+all_caps_2:	
+	movlw	.96
+	cpfsgt	PRODL
+	bra	all_caps_1			; <97 ("a") -> skip character
+
+	movlw	.123
+	cpfslt	PRODL
+	bra	all_caps_1			; >122 ("z") -> skip character
+	
+	movf	POSTDEC2,W			; dummy decrease FSR2
+	movlw	.32
+	subwf	PRODL,W				; make caps by subtracting .32
+	movwf	INDF2				; store caps version of INDF2 back into buffer
+	bra	all_caps_1			; check next char
+
+all_caps_3:
+	return					; done
+
+    
+	
 ;------------------------------------------------------------------------------
 ; Print the Output Buffer to Screen
 ;
@@ -500,6 +544,8 @@
 ;
 	global	aa_wordprocessor
 aa_wordprocessor:
+	btfsc	dn_flag
+	rcall	all_caps			; make the string "all caps"
 	movf	font_color,W			; get selected font color (8 bit)
 	call	TFT_set_color			; compute printing color (16 bit)
 	rcall	aa_string_width			; set win_height and compute win_width:2
@@ -508,6 +554,8 @@
 	movlw	0x22				; frame memory data write start
 	btfsc	screen_type4
 	movlw	0x2C				; Start Writing Data to GRAM (Display 4)
+	btfsc	screen_type5
+	movlw	0x2C				; Start Writing Data to GRAM (Display 5)
 	call	TFT_CmdWrite
 aa_wordprocessor_1:
 	movf	POSTINC2,W				; read character from the buffer
--- a/src/adc_lightsensor.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/adc_lightsensor.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -47,17 +47,16 @@
 	btfss	battery_gauge_available			; battery gauge IC available?
 	bra		get_battery_voltage_2			; NO  - OSTC hardware without gauge IC
 	bsf		battery_is_36v					; YES - gauge IC available, 3.6V battery
-	call	lt2942_get_accumulated_charge	;     - read coulomb counter
-	call	lt2942_get_voltage				;     - read battery voltage
+	call	lt2942_get_voltage				;     - read battery voltage (and coulomb counter)
 	call	lt2942_get_temperature			;     - read battery temperature
 	tstfsz	batt_voltage+1					;     - read voltage < 256 mV ?
 	bra		get_battery_voltage_1			;       NO  - proceed
-	call	lt2942_get_accumulated_charge	;       YES - re-read coulomb counter
-	call	lt2942_get_voltage				;           - re-read battery voltage
+	call	lt2942_get_voltage				;           - re-read battery voltage  (and coulomb counter)
 	call	lt2942_get_temperature			;           - re-read battery temperature
 	;bra	get_battery_voltage_1			;           - proceed
 
 get_battery_voltage_1:
+;	rcall	double_check_battery_percent		; make sure batt_percent is adjusted when voltage does not comply with the computed value
 	rcall	get_battery_voltage_low			; check for battery low condition
 	btfsc	divemode						; in dive mode?
 	return									; YES - done
@@ -88,8 +87,8 @@
 charge_cv_active1:
 	decfsz	get_bat_volt_counter,F			; decrement counter, became zero?
 	return									; NO  - not yet, done
-	movlw	.15								; YES - battery voltage >= 16*256mV (4.096V)
-	cpfsgt	batt_voltage+1					;     - ... ?
+	movlw	.16								; YES - battery voltage >= 16*256mV (4.096V) and < 17*256mV (4.352V)
+	cpfseq	batt_voltage+1					;     - ... ?
 	bra		charge_cc_active				;     NO
 	bsf		cc_active						;     YES - set CC charging status
 	bsf		cv_active						;         - set CV charging status
@@ -127,6 +126,53 @@
 	movlw	.10								;       NO  - set counter to 10
 	movwf	get_bat_volt_counter			;           - ...
 	return									;           - done
+	
+double_check_battery_percent:		; make sure batt_percent is adjusted when voltage does not comply with the computed value	
+	; batt_voltage:2 is in mV
+	; use thresholds rechargeable_36V_80 to rechargeable_36V_00
+	; return, if computed value is lower then fixed threshold
+	; overwrite batt_percent if computed value is bigger then threshold
+	; in 2024, it's no longer enough to explain the old behavior in the manual...
+	; used up as temp here
+	movlw	.100
+	movwf	up							; initialize
+	
+	MOVII	batt_voltage,sub_b
+	MOVLI	rechargeable_36V_80,sub_a				; load threshold 80%
+	call	cmpU16							; sub_a - sub_b
+	movlw	.80
+	btfss	neg_flag						; battery voltage > rechargeable_36V_80 ?
+	movwf	up							; no, overwrite up with a fix value
+	MOVII	batt_voltage,sub_b
+	MOVLI	rechargeable_36V_60,sub_a				; load threshold 60%
+	call	cmpU16							; sub_a - sub_b
+	movlw	.60
+	btfss	neg_flag						; battery voltage > rechargeable_36V_60 ?
+	movwf	up							; no, overwrite up with a fix value
+	MOVII	batt_voltage,sub_b
+	MOVLI	rechargeable_36V_40,sub_a				; load threshold 40%
+	call	cmpU16							; sub_a - sub_b
+	movlw	.40
+	btfss	neg_flag						; battery voltage > rechargeable_36V_40 ?
+	movwf	up							; no, overwrite up with a fix value
+	MOVII	batt_voltage,sub_b
+	MOVLI	rechargeable_36V_20,sub_a				; load threshold 20%
+	call	cmpU16							; sub_a - sub_b
+	movlw	.20
+	btfss	neg_flag						; battery voltage > rechargeable_36V_20 ?
+	movwf	up							; no, overwrite up with a fix value
+	MOVII	batt_voltage,sub_b
+	MOVLI	rechargeable_36V_00,sub_a				; load threshold 0%
+	call	cmpU16							; sub_a - sub_b
+	movlw	.0
+	btfss	neg_flag						; battery voltage > rechargeable_36V_0 ?
+	movwf	up							; no, overwrite up with a fix value
+	
+	movf	up,W
+	cpfsgt	batt_percent						; up < batt_percent
+	return
+	movwf	batt_percent						; YES, overwritze
+	return
 
 get_battery_voltage_2:						; no gauge IC available, use ADC to measure battery voltage
 	; additional charging disable in software
@@ -283,15 +329,15 @@
 get_ambient_level0:	
 	banksel	isr_backup						;             NO  - back to ISR default bank
 	movff	brightness,isr_lo			;                 - get brightness selection
-	incf	isr_lo,F						;                 - 0-2 -> 1-3
-	movlw	ambient_light_max_high_cr		;                 - default selection to brightest setting
-	dcfsnz	isr_lo,F						;                 - level 0 (eco) selected?
-	movlw	ambient_light_max_eco			;                   YES - select eco brightness
-	dcfsnz	isr_lo,F						;                 - level 1 (medium) selected?
-	movlw	ambient_light_max_medium		;                   YES - select medium brightness
-	movwf	ambient_light+0					;                 - store selection
-	movwf	max_CCPR1L						;                 - store value for dimming in TMR7 interrupt
-	return									;                 - done
+	incf	isr_lo,F				;                 - 0-2 -> 1-3
+	movlw	ambient_no_sensor_high			;                 - default selection to brightest setting
+	dcfsnz	isr_lo,F				;                 - level 0 (eco) selected?
+	movlw	ambient_no_sensor_eco			;                   YES - select eco brightness
+	dcfsnz	isr_lo,F				;                 - level 1 (medium) selected?
+	movlw	ambient_no_sensor_medium		;                   YES - select medium brightness
+	movwf	ambient_light+0			    	;                 - store selection
+	movwf	max_CCPR1L				;                 - store value for dimming in TMR7 interrupt
+	return						;                 - done
 
 get_ambient_level1:							; using ambient sensor
 	banksel	isr_backup						; back to ISR default bank
@@ -299,13 +345,16 @@
 	movlw	b'00011101'						; power on ADC, select AN7
 	rcall	wait_adc
 	MOVII	ADRESL,ambient_light
+;	MOVII	ADRESL,gp_debug	; for debugging only
 	bcf	ADCON0,0						; power off ADC
 
 	btfsc	ambient_light+1,7					; result negative?
 	return								; Yes, skip this measurement
 	; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness)
 	; first: divide by 16
-	movlw	.4								; divide by 2^4 = 16
+	movlw	.4					; divide by 2^4 = 16
+	btfsc	dn_flag
+	movlw	.1					; divide by 1^4 = 4, increased sensitivity for dn hardware
 get_ambient_level1_loop:
 	bcf		STATUS,C						; clear carry
 	rrcf	ambient_light+1					; rotate right high byte, carry into MSB, LSB into carry
@@ -338,8 +387,10 @@
 	movlw	ambient_light_max_high_cr		; default to cR and 2 hardware brightest setting
 	btfss	battery_gauge_available			; battery gauge available?
 	movlw	ambient_light_max_high_15V		; NO  - change to 1.5V battery brightest setting
-	btfsc	battery_is_36v					; 3.6V battery in use?
+	btfsc	battery_is_36v				; 3.6V battery in use?
 	movlw	ambient_light_max_high_36V		; YES - change to 3.6V battery brightest setting
+	btfsc	dn_flag					; dn hardware
+	movlw	ambient_light_max_high_dn		; YES - change to dn hardware brightest setting
 	banksel	isr_backup						; back to ISR default bank
 
 	dcfsnz	isr_lo,F						; eco setting?
@@ -373,7 +424,7 @@
 ;
 ; called from outside ISR only
 ;
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 	global	get_analog_inputs
 get_analog_inputs:
@@ -433,7 +484,7 @@
 	clrf	mpr+0							;       NO - ignore this reading
 	return									;     - done
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 
 ;-----------------------------------------------------------------------------
--- a/src/adc_lightsensor.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/adc_lightsensor.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -13,6 +13,6 @@
 	extern	piezo_config					; set up piezo sensitivity of heinrichs weikamp piezo buttons (~30ms)
 	extern	get_analog_switches				; get analog switches
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	extern	get_analog_inputs				; get AN8-10
  ENDIF
--- a/src/calibrate.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/calibrate.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -19,30 +19,31 @@
 ;=============================================================================
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Transmit current Setpoint from WREG (in cbar) to external Electronics
 ;
 	global	transmit_setpoint
 transmit_setpoint:
-	return									; !!!! FUNCTION IS CURRENTLY DISABLED !!!!
-
-;	btfsc	ext_input_optical				; optical input in use?
-;	return									; YES - setpoint - TX not supported
-;	TSTOSS	opt_s8_mode						; NO  - S8 mode selected?
-;	return									;       NO
-;	clrf	lo								;       YES - initialize checksum
-;	movff	char_I_const_ppO2,hi			;           - copy setpoint value to hi
-;	movlw	0xAA							;           - load start byte
-;	rcall	tx_to_HUD_chksum				;           - transmit to HUD
-;	movlw	0x60							;           - load command 'new SP'
-;	rcall	tx_to_HUD_chksum				;           - transmit to HUD
-;	movf	hi,W							;           - load SP in cbar
-;	rcall	tx_to_HUD_chksum				;           - transmit to HUD
-;	movf	lo,W							;           - load checksum
-;	rcall	tx_to_HUD						;           - transmit checksum
-;	return									;           - done
+	btfsc	ext_s8_full_digital			;  are we in external S8 full digital mode? 
+	bra	transmit_setpoint2				    ; Yes, alsway TX Setpoint	
+	btfsc	ext_input_optical				; optical input in use?
+	return									; YES - setpoint - TX not supported
+	TSTOSS	opt_s8_mode						; NO  - S8 mode selected?
+	return									;       NO
+transmit_setpoint2:
+	clrf	lo								;       YES - initialize checksum
+	movff	char_I_const_ppO2,hi			;           - copy setpoint value to hi
+	movlw	0xAA							;           - load start byte
+	rcall	tx_to_HUD_chksum				;           - transmit to HUD
+	movlw	0x70							;           - load command 'new SP'
+	rcall	tx_to_HUD_chksum				;           - transmit to HUD
+	movf	hi,W							;           - load SP in cbar
+	rcall	tx_to_HUD_chksum				;           - transmit to HUD
+	movf	lo,W							;           - load checksum
+	rcall	tx_to_HUD						;           - transmit checksum
+	return									;           - done
 
 
 ;-----------------------------------------------------------------------------
@@ -73,6 +74,8 @@
 	; check for HUD
 	btfsc	ext_input_optical				; optical interface in use?
 	bra		calibrate_mix1					; YES - skip
+	btfsc	ext_s8_full_digital			;  are we in external S8 full digital mode? 
+	bra		calibrate_mix1					; YES - skip
 	TSTOSS	opt_s8_mode						; NO  - S8 interface in use?
 	bra		calibrate_mix1					;       NO  - skip HUD part
 	;bra	calibrate_mix0					;       YES - calibrate S8 HUD
@@ -193,13 +196,13 @@
 
 	retlw	.0								; return signaling min/max ok
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 ;=============================================================================
 calibrate2	CODE
 ;=============================================================================
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Compute Sensor mV from Raw Values received via S8 digital Interface
@@ -234,7 +237,7 @@
 
 	return									; done
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 
--- a/src/calibrate.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/calibrate.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -5,7 +5,7 @@
 ;=============================================================================
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	extern	calibrate_mix					; calibrate sensors
 	extern	compute_mvolts_from_rawdata		; compute sensor mV values from digital transmitted data
 	extern	transmit_setpoint				; transmit current setpoint to external electronics
Binary file src/clib.lib has changed
--- a/src/color_processor.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/color_processor.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -100,6 +100,8 @@
 	movlw	0x22				; frame memory data write start
 	btfsc	screen_type4
 	movlw	0x2C				; Start Writing Data to GRAM (Display 4)
+	btfsc	screen_type5
+	movlw	0x2C				; Start Writing Data to GRAM (Display 5)
 	call	TFT_CmdWrite
 color_image_loop_xy:
 	; prepare to read next pixel count and color
--- a/src/comm.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/comm.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -104,8 +104,9 @@
 ;
 comm_mode_common:
 	clrf	STKPTR									; reset addresses stack
+	call	enable_rs232							; enable serial comm, also sets CPU to normal speed (init here, we need the aux_flag valid)
 	call	TFT_ClearScreen							; clear screen
-	FONT_COLOR color_greenish						; set color
+	FONT_COLOR color_green						; set color
 
 	btfss	aux_flag								; shall show USB title?
 	bra		comm_mode_common_bt						; NO  - show BT  title
@@ -114,32 +115,32 @@
 comm_mode_common_usb:
 	WIN_SMALL comm_title_column_usb, comm_title_row	; set   USB title position
 	STRCPY_TEXT_PRINT tUsbTitle						; print USB title text
-	bra		comm_mode_common_logo					; continue with logo
+	bra		comm_mode_common_start
 
 comm_mode_common_bt:
 	WIN_SMALL comm_title_column_ble, comm_title_row	; set   BT title position
 	STRCPY_TEXT_PRINT tBleTitle						; print BT title text
-	;bra	comm_mode_common_logo					; continue with logo
-
-comm_mode_common_logo:
-	WIN_TOP  .10									; set position of USB/BLE logo, row
-	WIN_LEFT .1										; set position of USB/BLE logo, column
-	btfss	battery_gauge_available					; "+" bootloader ?
-	bra		comm_mode_common_logo2					; YES - show logo type 2
-	;bra	comm_mode_common_logo1					; NO  - show logo type 1
+	;bra	comm_mode_common_start
 
-comm_mode_common_logo1:
-	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_1		; show USB/BT logo
-	bra		comm_mode_common_start					; continue with starting message
-
-comm_mode_common_logo2:
-	btfsc	dn_flag
-	bra	comm_mode_common_logo3
-	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_2		; show BT logo / OSTC+
-	bra	comm_mode_common_start					; continue with starting message
-
-comm_mode_common_logo3:
-	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_3		; show BT logo / dn
+;comm_mode_common_logo:
+;	WIN_TOP  .10									; set position of USB/BLE logo, row
+;	WIN_LEFT .1										; set position of USB/BLE logo, column
+;	btfss	battery_gauge_available					; "+" bootloader ?
+;	bra		comm_mode_common_logo2					; YES - show logo type 2
+;	;bra	comm_mode_common_logo1					; NO  - show logo type 1
+;
+;comm_mode_common_logo1:
+;    	btfsc	dn_flag
+;	bra	comm_mode_common_logo3
+;	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_1		; show USB/BT logo
+;	bra		comm_mode_common_start					; continue with starting message
+;
+;comm_mode_common_logo2:
+;	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_2		; show BT logo / OSTC+
+;	bra	comm_mode_common_start					; continue with starting message
+;
+;comm_mode_common_logo3:
+;	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_3		; show BT logo / dn
 	
 comm_mode_common_start:
 	WIN_SMALL comm_status1_column,comm_status1_row	; set position
@@ -154,8 +155,9 @@
  ENDIF
 
 	bcf		switch_right							; clear potential left-over right button event
-	call	enable_rs232							; enable serial comm, also sets CPU to normal speed
-
+	TSTOSC	opt_BLE_compatibility				; Use BLE compatibility mode?
+	call	ble2_configure_name				; YES, setup BLE name (Will only do something for dn_mode flag set)
+	
 	WIN_SMALL comm_status1_column+.80,comm_status1_row	; set position after starting message
 	FONT_COLOR_MEMO										; set standard color
 	STRCPY_TEXT_PRINT tUsbStartDone						; print (adding to status message) "done..."
@@ -186,6 +188,8 @@
 	bz		comm_download_mode						;             YES - enter command loop
 	;bra	comm_mode_selection_loop_2				;             NO  - check for comm mode termination
 comm_mode_selection_loop_2:
+	btfsc	dual_comm							; Dual comm hardware?
+	bra		comm_mode_selection_loop_3				; YES - skip USB check check since vusb_in is only used for usb here
 	btfsc	ble_available							; BT available?
 	bra		comm_mode_selection_loop_3				; YES - skip USB check check (required for very old OSTC sport)
 	btfss	vusb_in									; NO  - USB plugged in?
@@ -321,6 +325,8 @@
 	bra		comm_command_decode						; NO  - decode and execute the command
 	btfsc	comm_service_mode						; YES - service mode enabled?
 	btg		LEDr									;       YES - blink in service mode
+	btfsc	dual_comm							; Dual comm hardware?
+	bra		comm_command_loop_wait_1				; YES - skip USB check check since vusb_in is only used for usb here
 	btfsc	ble_available							;     - BT available?
 	bra		comm_command_loop_wait_1				;       YES - skip USB check (required for very old OSTC sport)
 	btfss	vusb_in									;       NO  - USB still plugged in?
--- a/src/compass_ops.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/compass_ops.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -25,14 +25,14 @@
 
 
 ; local flags
-#DEFINE compass_show_cardinal	compass_flags,0		; =1: show the cardinal (N, NE, E, ...)
-#DEFINE compass_bearing_eq		compass_flags,1		; =1: bearing is in direction, do not show << or >> 
-#DEFINE compass_bearing_lft		compass_flags,2		; =1: bearing is to the left/<<, =0: to the right/>>
-#DEFINE compass_bearing_vis		compass_flags,3		; =1: bearing is visible (either ahead or behind/-180°)
-#DEFINE compass_bearing_ahd		compass_flags,4		; =1: bearing is ahead, =0: behind
-;								compass_flags,5		; --- unused
-;								compass_flags,6		; --- unused
-;								compass_flags,7		; --- unused
+;#DEFINE compass_show_cardinal	compass_flags,0		; =1: show the cardinal (N, NE, E, ...)
+;#DEFINE compass_bearing_eq		compass_flags,1		; =1: bearing is in direction, do not show << or >> 
+;#DEFINE compass_bearing_lft		compass_flags,2		; =1: bearing is to the left/<<, =0: to the right/>>
+;#DEFINE compass_bearing_vis		compass_flags,3		; =1: bearing is visible (either ahead or behind/-180°)
+;#DEFINE compass_bearing_ahd		compass_flags,4		; =1: bearing is ahead, =0: behind
+;;								compass_flags,5		; --- unused
+;;								compass_flags,6		; --- unused
+;;								compass_flags,7		; --- unused
 
 
 ; Make sure symbols from the .inc are available to the C code:
@@ -222,7 +222,7 @@
 	call	TFT_ClearScreen				; clear the screen
 	; Mask
 	WIN_STD .16,.0						; set position
-	FONT_COLOR color_greenish			; set font color
+	FONT_COLOR color_green			; set font color
 	STRCPY_TEXT_PRINT tCompassCalibration
 	btfss	switch_right2				; wait until button (with a moving magnet in some OSTC!) is released
 	bra		$-2
@@ -477,7 +477,7 @@
 	global	TFT_surface_compass_mask
 TFT_surface_compass_mask:
 	WIN_SMALL surf_compass_mask_column,surf_compass_mask_row
-	FONT_COLOR_MEMO						; set font color
+	FONT_COLOR color_green				; set font color
 	STRCPY_TEXT_PRINT tHeading			; print "Heading:"
 	return								; done
 
@@ -530,9 +530,11 @@
 ;-----------------------------------------------------------------------------
 ; Mask for Compass in Dive Mode
 ;
-	global	TFT_dive_compass_mask		; draws the white box around the heading tape
+	global	TFT_dive_compass_mask
 TFT_dive_compass_mask:
-	WIN_FRAME_STD dm_custom_compass_graph_row, dm_custom_compass_graph_row+dm_custom_compass_graph_height, .0, .159
+	FONT_COLOR_MASK						; select color
+    	WIN_TINY dm_custom_compass_mask_column,dm_custom_compass_mask_row
+	STRCPY_TEXT_PRINT tCompassMenu				; print label
 	return
 
 
@@ -542,628 +544,26 @@
 	global	TFT_dive_compass_heading
 TFT_dive_compass_heading:
 	call	compass_heading_common		; compute heading
-
-;	; ### for development only, hard-coding the bearing ###
-;	; 244° : SW - W
-;	MOVLI	.244,xA						; xA used as temp
-;	MOVII	xA,compass_bearing			; compass_bearing is stored in bank isr_backup
-
-	FONT_SIZE FT_SMALL					; set font size
-	MOVII	compass_heading_shown,xA	; get heading
-	; 160° viewing angle: add +360 offset if xA <= 292 for non-negative scale
-	MOVLI	.292,sub_a
-	MOVII	xA,  sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; xA > 292 ?
-	bra		TFT_dive_compass_heading_1	; YES
-	ADDLI	.360,xA						; NO  - add offset
-TFT_dive_compass_heading_1:
-	SUBLI	.80,xA						; subtract 80 (left pixel offset from the center)
-	MOVII	xA,xRD						; save result to xRD
-	ADDLI	.160,xA						; add 160 (display with in pixels)
-	MOVII	xA,xRDr						; save result to xRDr
-
+	; Text output
+	FONT_COLOR_MEMO						; set default / dive-mode standard color
+	WIN_MEDIUM dm_custom_compass_head_column, dm_custom_compass_head_row
+	MOVII	compass_heading_shown,mpr	; get heading to be shown
+	bsf	leading_zeros
+	output_999							; print bearing
+	bcf	leading_zeros
+	PRINT								; dump to screen
+	WIN_STD dm_custom_compass_unit_column, dm_custom_compass_unit_row
+	STRCAT	"°"
+	call	tft_compass_cardinal		; append cardinal buffer
+	PRINT
+	; shall show bearing?
 	btfss	compass_bearing_set			; is a bearing set?
-	bra		TFT_dive_compass_ruler		; NO  - skip next calculations
-	MOVII	xRDr,sub_a					; YES - calculate xRD180 = xRDr - 180
-	MOVLI	.180,sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	MOVII	sub_c,xRD180
-
-TFT_dive_compass_bearing_1:
-	; calculate bearing position and visibility (ahead or behind)
-	bcf		compass_bearing_vis			; default is not-visible
-	bcf		compass_bearing_ahd			; default is behind
-	MOVII	compass_bearing,xA
-	ADDLI	.360,xA						; calculate the bearing virtual display offset
-	MOVII	xA,divA						; save it for reuse for upper/lower turns and ahead/behind checks
-
-	; check if bearing is ahead
-	MOVII	divA,sub_a					; load the bearing offset into sub_a
-	MOVII	xRD, sub_b					; load the display offset back to sub_b
-	rcall	TFT_dive_compass_bearing_ap
-	btfsc	compass_bearing_vis			; bearing visible?
-	bra		TFT_dive_compass_bearing_dir; YES
-
-	; check if it is ahead with an upper turn
-	MOVII	divA,sub_a					; load the bearing offset into sub_a
-	MOVII	xRD, sub_b					; load the display offset back to sub_b
-	ADDLI	.360,sub_b
-	rcall	TFT_dive_compass_bearing_ap
-	btfsc	compass_bearing_vis			; bearing visible?
-	bra		TFT_dive_compass_bearing_dir; YES
-
-	; check if it is ahead with a lower turn
-	MOVII	divA,sub_a					; load the bearing offset into sub_a
-	ADDLI	.360,sub_a
-	MOVII	xRD, sub_b					; load the display offset back to sub_b
-	rcall	TFT_dive_compass_bearing_ap
-	btfsc	compass_bearing_vis			; bearing visible?
-	bra		TFT_dive_compass_bearing_dir; YES
-
-	; marker is not ahead of us, check if it is behind of us
-	; use the (160 - (xRD180 - xCM)) formula to see if it's on the display
-	MOVII	xRD180,sub_a				; load the display offset back to sub_a
-	MOVII	divA,  sub_b				; load the marker's offset into sub_b
-	rcall	TFT_dive_compass_bearing_bp
-	btfsc	compass_bearing_vis			; bearing behind of us?
-	bra		TFT_dive_compass_bearing_dir; YES
-
-	; check if it is behind with the upper turn
-	MOVII	xRD180,sub_a
-	MOVII	divA,  sub_b
-	ADDLI	.360,  sub_b
-	rcall	TFT_dive_compass_bearing_bp
-	btfsc	compass_bearing_vis			; bearing behind of us?
-	bra		TFT_dive_compass_bearing_dir; YES
-
-	; check if it is behind with the lower turn
-	MOVII	xRD180,sub_a
-	ADDLI	.360,  sub_a
-	MOVII	divA,  sub_b				; load the marker's offset into sub_b
-	rcall	TFT_dive_compass_bearing_bp
-	bra		TFT_dive_compass_bearing_dir
-
-TFT_dive_compass_bearing_ap:
-	; xCM received in sub_a
-	; xRD received in sub_b
-	; 1/a. check if it's viewable from the left side
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; xRD > divA ?
-	return								; NO  - done
-	MOVII	sub_c,xC					; YES - store the RO=RP-RD for drawing
-	; 1/b. check if it's viewable from the right side
-	ADDLI	  .2,sub_a					; avoid thin mess on the side of the display
-	ADDLI	.158,sub_b					; load the display offset right side into sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfss	neg_flag					; xRDr > xA(+2) ?
-	return								; NO  - done
-										; YES - print the bearing lines on the screen
-	movff	xC+0,xCM
-	bsf		compass_bearing_vis			; set visible
-	bsf		compass_bearing_ahd			; set ahead
-	return								; done
-
-TFT_dive_compass_bearing_bp:
-	; use the (160 - (xRD180 - xCM)) formula to see if it's on the display
-	; the marker's offset received in sub_b
-	; the xRD180 display offset received in sub_a
-	; xRD180 - xCM
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; CM > xRD180 ?
-	return								; NO -  not on screen, done
-										; YES - check 160 - (X)
-	MOVLI	.158, sub_a					; 158 to avoid thin mess on the side of the display
-	MOVII	sub_c,sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; X > 160 ?
-	return								; NO - not on screen, done
-	; check if not overflow - this sounds like a double check...
-	tstfsz	sub_c+1						; high byte = 0 ?
-	return								; NO - sub_c must be > 160 then, done
-	movlw	d'158'						; YES - load a 158
-	cpfslt	sub_c+0						;     - low byte < 158 ?
-	return								;       NO  - done
-	movff	sub_c+0,xCM					;       YES - print the bearing lines on the screen
-	bsf		compass_bearing_vis			;           - flag to show bearing lines
-	return								;           - done
-
-TFT_dive_compass_bearing_dir:
-	; check if bearing to heading, and calculate the direction
-	bcf		compass_bearing_eq
-	btfss	compass_bearing_vis
-	bra		TFT_dive_compass_bearing_lr
-	btfss	compass_bearing_ahd
-	bra		TFT_dive_compass_bearing_lr
-	movff	xCM,xA+0
-	movlw	d'80'
-	cpfseq	xA+0
-	bra		TFT_dive_compass_bearing_lr
-	bsf		compass_bearing_eq
-	bra		TFT_dive_compass_ruler		; bearing points to heading, no signs are required, go to the ruler
-
-TFT_dive_compass_bearing_lr:
-	; get the bearing virtual display offset
-	MOVII	compass_bearing,xA
-	; xA = xA > 292 ? xA : xA+360
-	MOVLI	.292,sub_a
-	MOVII	xA,  sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; xA > 292 ?
-	bra		TFT_dive_compass_bearing_lr_1; YES
-	ADDLI	.360,xA						; NO  - add 360
-
-TFT_dive_compass_bearing_lr_1:
-	; 1. calculate whether bearing is to left or to right
-	bsf		compass_bearing_lft			; to the left by default
-	; xC: save center value to compare the direction to front value
-	MOVII	xA,xC
-	; xB: we need the left side for comparison... left = -180
-	MOVII	xA,  sub_a
-	MOVLI	.180,sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	MOVII	sub_c,xB					; xB has the left side of the 180° distance center
-	; xA = xRD > (xC+100) ? RD-280 : xRD+80
-	MOVII	xC,  sub_a
-	ADDLI	.100,sub_a
-	MOVII	xRD, sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; xRD > xC + 100 ?
-	bra		TFT_dive_compass_bearing_lr_2; YES - xA = xRD - 280
-										; NO  - xA = xRD + 80
-	MOVII	xRD,xA
-	ADDLI	.80,xA
-	bra		TFT_dive_compass_bearing_lr_c
-
-TFT_dive_compass_bearing_lr_2:
-	MOVII	xRD,sub_a
-	MOVLI	.280,sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	MOVII	sub_c,xA
-	;bra	TFT_dive_compass_bearing_lr_c
-
-TFT_dive_compass_bearing_lr_c:
-	; xB < xA < xC => right, otherwise left (default)
-	MOVII	xA,sub_b
-	MOVII	xB,sub_a
-	call	subU16						; sub_c = sub_a - sub_b
-	btfss	neg_flag					; xA > xB ?
-	bra		TFT_dive_compass_ruler		; NO - xB >= xA, keep default left
-	MOVII	xA,sub_a
-	MOVII	xC,sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfss	neg_flag					; xC > xA ?
-	bra		TFT_dive_compass_ruler		; NO - xA >= xC, keep default left
-	bcf		compass_bearing_lft
-
-TFT_dive_compass_ruler:
-	; calculate mod15 for the ticks
-	MOVII	xRD,xA
-	MOVLI	.15,xB
-	call	div16x16					; xA/xB=xC with xA+0 as remainder
-	; check the remainder
-	movlw	d'0'
-	cpfsgt	xA+0						; mod15 > 0 ?
-	bra		TFT_dive_compass_ruler_1	; NO  - RM = 0
-										; YES - RM = 15 - RDmod15
-	movlw	d'15'
-	subfwb	xA+0,F
-TFT_dive_compass_ruler_1:
-	movff	xA+0,lo						; xA+0 holds the RM, store it to 'lo'
-	clrf	hi							; initialize DD to zero, store it to 'hi'
-
-TFT_dive_compass_ruler_loop:
-	; 1. check if we run out of the display
-	movlw	d'159'						; looks like 159 works because TFT_box limits the display
-	cpfslt	lo,1
-	bra		TFT_dive_compass_ruler_lend	; xRM >= W
-	; 2. Clear the tick area from DD to RM - in segments to avoid blinking
-	;    don't do a clear if we are at 0 (zero) otherwise it will blink
-	;    because of the width underflow
-	movlw	d'0'
-	cpfsgt	lo,1
-	bra		TFT_dive_compass_ruler_loop_zz
-	rcall	TFT_dive_compass_clr_ruler
-TFT_dive_compass_ruler_loop_zz:
-	; 3. Draw the markers @ RM
-	;    we receive RM in lo and DD in hi
-	movlw	d'2'
-	movwf	win_bargraph				; set with of  ticks
-	movwf	win_width+0
-	clrf	win_width+1
-	movff	lo,win_leftx2				; 0..159
-	movlw	dm_custom_compass_tick_top_top
-	movwf	win_top						; set position for upper ticks
-	movlw	dm_custom_compass_tick_height
-	movwf	win_height					; set hight of ticks
-	movf	pallet_color_memo,W			; select color
-	BOX_COLOR							; draw tick
-	movlw	dm_custom_compass_tick_bot_top
-	movwf	win_top						; set position for lower ticks
-	movlw	dm_custom_compass_tick_height
-	movwf	win_height					; set hight of ticks
-	movf	pallet_color_memo,W			; select color
-	BOX_COLOR							; draw tick
-	; 4. If D < 82 and RM > 79: means we put something over the center line,
-	;							so redraw the center line
-	movlw	d'82'
-	cpfslt	hi,1
-	bra		TFT_dive_compass_ruler_loop_zz2
-	movlw	d'79'
-	cpfsgt	lo,1
-	bra		TFT_dive_compass_ruler_loop_zz2
-	; enough to print center line as bearing marker is not in the ticker area
-	rcall	TFT_dive_compass_c			; draw center line in yellow
-TFT_dive_compass_ruler_loop_zz2:
-	; 5. set D = RM + 2 : position after the 2px tick
-	movff	lo,hi
-	movlw	d'2'
-	addwf	hi,F
-	; 6. set RM = RM + 15 : position to the next tick
-	movlw	d'15'
-	addwf	lo,F
-	; 7. loop
-	bra		TFT_dive_compass_ruler_loop
-
-TFT_dive_compass_ruler_lend:			; loop end
-	; 8. clear the rest of the tick area if D < 160
-	movlw	d'160'
-	cpfslt	hi
-	bra		TFT_dive_compass_labels		 ; D >= W
-	; 9. position left to end of display to clear the remaining area
-	movlw	d'159'
-	movwf	lo
-	; 10. clear it
-	rcall	TFT_dive_compass_clr_ruler
-
-TFT_dive_compass_labels:
-	; done with the compass ruler, put the labels on the screen
-	FONT_COLOR_MEMO						; set dive-mode standard color
-	clrf	hi							; hi stores the display position
-	movff	hi,xHI						; bank-safe clear of xHI
-	clrf	lo							; lo stores the last item's display position
-	movff	lo,xLO						; bank-safe clear of xLO
-	MOVLI	.219,sub_a					; position of the cardinal
-	MOVII	xRD, sub_b					; get the RD back to sub_b
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_1						; NO
-	STRCPY_TEXT_PRINT tSW				; YES - print it
-dcr_1:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.267,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_2						; NO
-	STRCPY_TEXT_PRINT tW				; YES - print it
-dcr_2:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.309,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_3						; NO
-	STRCPY_TEXT_PRINT tNW				; YES - print it
-dcr_3:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.358,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_4						; NO
-	STRCPY_TEXT_PRINT tN				; YES - print it
-dcr_4:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.399,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_5						; NO
-	STRCPY_TEXT_PRINT tNE				; YES - print it
-dcr_5:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.448,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_6						; NO
-	STRCPY_TEXT_PRINT	tE				; YES - print it
-dcr_6:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.489,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_7						; NO
-	STRCPY_TEXT_PRINT	tSE				; YES - print it
-dcr_7:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.538,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_8						; NO
-	STRCPY_TEXT_PRINT tS				; YES - print it
-dcr_8:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.579,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_9						; NO
-	STRCPY_TEXT_PRINT tSW				; YES - print it
-dcr_9:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.627,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_10						; NO
-	STRCPY_TEXT_PRINT tW				; YES - print it
-dcr_10:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.669,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show cardinal?
-	bra		dcr_11						; NO
-	STRCPY_TEXT_PRINT tNW				; YES - print it
-dcr_11:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	MOVLI	.718,sub_a					; position of the cardinal
-	rcall	TFT_dive_compass_label_proc	; check if the cardinal shall be on screen
-	btfss	compass_show_cardinal		; shall show?
-	bra		dcr_12						; NO
-	STRCPY_TEXT_PRINT tN				; YES - print it
-dcr_12:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-
-TFT_dive_compass_label_end:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	; restore lo and hi for the final cleanup
-	movff	xLO,lo						; xLO and xHI are stored in bank isr_backup
-	movff	xHI,hi
-	; clear the rest of the SQ area if there is more space
-	movlw	d'159'
-	cpfslt	hi
-	bra		TFT_dive_compass_label_end2	; D >= 160, no more space
-	; position left to end of display to clear the remaining area
-	movlw	d'158'
-	movwf	lo
-	; clear it
-	rcall	TFT_dive_compass_clr_label
-TFT_dive_compass_label_end2:
-	rcall	TFT_dive_compass_c_mk		; check if cardinal is on the center line or the marker
-	; do we have bearing set?
-	btfsc	compass_bearing_set			; bearing set?
-	bra		TFT_dive_compass_dir_text	; YES - print the direction (<< or >>)
-	rcall	TFT_dive_compass_dir_lclr	; NO  - clear the area (e.g. we had but removed)
-	rcall	TFT_dive_compass_dir_rclr
-	bra		TFT_dive_compass_text
-
-TFT_dive_compass_dir_text:
-	; bearing set, but does it point to heading?
-	btfss	compass_bearing_eq
-	bra		TFT_dive_compass_dir_text_2	; bearing != heading - go and print the direction
-	rcall	TFT_dive_compass_dir_lclr	; bearing == heading - no need for direction markers
-	rcall	TFT_dive_compass_dir_rclr
-	bra		TFT_dive_compass_text
-
-TFT_dive_compass_dir_text_2:
-	FONT_COLOR color_green
-	btfsc	compass_bearing_lft
-	bra		TFT_dive_compass_dir_ldir	; bearing_lft=1, print the left marker
-;TFT_dive_compass_text_rdir:
-	WIN_SMALL dm_custom_compass_rdir_column, dm_custom_compass_head_row-.2
-	STRCPY_PRINT ">>"
-	rcall	TFT_dive_compass_dir_lclr	; do not forget to clear the left
-	bra		TFT_dive_compass_text
-
-TFT_dive_compass_dir_ldir:
-	WIN_SMALL dm_custom_compass_ldir_column, dm_custom_compass_head_row-.2
-	STRCPY_PRINT "<<"
-	rcall	TFT_dive_compass_dir_rclr	; do not forget to clear the right
-	;bra	TFT_dive_compass_text
-
-TFT_dive_compass_text:
-	; Clear some unused space on the right mH
-	WIN_BOX_BLACK dm_custom_compass_tick_top_bot+.1,dm_custom_compass_tick_bot_top-.1,.158,.159	; top, bottom, left, right
-
-	; Text output
-	WIN_SMALL dm_custom_compass_head_column, dm_custom_compass_head_row
-	call	TFT_surface_compass_heading_com	; show "xxx° N"
-	return
-
-TFT_dive_compass_dir_lclr:
-	WIN_SMALL dm_custom_compass_ldir_column, dm_custom_compass_head_row-.2
-	STRCPY_PRINT "  "
-	return
-
-TFT_dive_compass_dir_rclr:
-	WIN_SMALL dm_custom_compass_rdir_column, dm_custom_compass_head_row-.2
-	STRCPY_PRINT "  "
-	return
-
-TFT_dive_compass_label_proc:
-	movlw	d'14'
-	movwf	up							; cardinal width in px
-	bcf		compass_show_cardinal
-	; 1/a. check if it's viewable ? sub_a(RP) >= sub_b(RD) ?
-	;      set the carry flag if sub_b(xRD) is equal to or greater than sub_a(xRP):
-	MOVII	xRD,sub_b
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag					; >= 0 ?
-	return								; NO
-	; store the RO=RP-RD for drawing
-	MOVII	sub_c,xC
-
-	; 1/b. check if it's viewable ? sub_a(RP)+up(width) < sub_b(RD)+160
-	;      if already above, no need to process the rest of the labels
-	movff	up,WREG						; take care about the width
-	addwf	sub_a+0,1
-	btfsc	STATUS, C
-	incf	sub_a+1
-
-	MOVII	xRDr,sub_b
-	call	subU16	 					; sub_c = sub_a - sub_b
-	btfss	neg_flag					; < 0 ?
-	bra		TFT_dive_compass_label_end	; NO
-
-	; 2. restore RO=RP-RD from 1/a.
-	movff	xC+0,lo
-
-	; 3. Clear the segment from DD(hi) to lo
-	;    don't do a clear if we are at 0 (zero) otherwise it will blink
-	;   ?because of the width underflow?
-	movlw	d'1'
-	cpfsgt	lo
-	bra		TFT_dive_compass_label_proc_p
-	rcall	TFT_dive_compass_clr_label
-TFT_dive_compass_label_proc_p:
-	; 4. print the SQ on the screen
-	FONT_COLOR_MEMO
-	bsf		compass_show_cardinal
-;TFT_dive_compass_label_print:
-	movlw	dm_custom_compass_label_row	; set output position
-	movff	WREG,win_top				; ...
-	movff	lo,win_leftx2				; ...
-	FONT_SIZE FT_SMALL					; set font size
-	; 6. retain the new display positions
-	movff	lo,hi
-	movff	up,WREG
-	addwf	hi,F
-	movff	lo,xLO
-	movff	hi,xHI
-	return
-
-TFT_dive_compass_c_mk:
-	; Common task to draw center line and marker
-	; until a proper implementation make it simple:
-	rcall	TFT_dive_compass_mk
-TFT_dive_compass_c:
-	movlw	color_yellow
-	WIN_BOX_COLOR dm_custom_compass_tick_top_top, dm_custom_compass_tick_bot_bot,.80,.81 ; center line in yellow
-	return
-
-TFT_dive_compass_mk:
-	; draw the bearing on the screen if visible and if we just put something over it
-	btfss	compass_bearing_set			; bearing set?
-	return								; NO  - done
-	btfss	compass_bearing_vis			; YES - bearing visible?
-	return								;       NO  - bearing set but not visible, done
-
-	; save lo/hi from trashing
-	MOVII	mpr,xA
-
-	; did we just update the marker's position?
-	; DD.......DD
-	; CM+2>=DD(old) or CM-2<=DD
-	; ToDo
-
-	btfss	compass_bearing_ahd
-	bra		TFT_dive_compass_mk_rear
-;TFT_dive_compass_mk_front:
-	clrf	lo
-	movff	xCM,lo
-	bsf		compass_show_cardinal		; set=green marker
-	rcall	TFT_dive_compass_mk_print
-	bcf		compass_show_cardinal
-	bra		TFT_dive_compass_mk_end
-
-TFT_dive_compass_mk_rear:
-	clrf	lo
-	movff	xCM,lo
-	bcf		compass_show_cardinal		; set=red marker
-	rcall	TFT_dive_compass_mk_print
-
-TFT_dive_compass_mk_end:
-	MOVII	xA,mpr
-	return
-
-TFT_dive_compass_mk_print:
-	movlw	d'1'
-	cpfsgt	lo
-	bra		TFT_dive_compass_mk_print_2	; lo <= 1, skip the first line
-	movlw	d'2'
-	subwf	lo,0
-;	movff	WREG,win_leftx2
-	rcall	TFT_dive_compass_mk_print_3
-TFT_dive_compass_mk_print_2:
-	; save hi/lo
-	MOVII	mpr,divA
-	; clear the middle of the bearing marker
-	movff	lo,hi
-	movlw	d'2'
-	addwf	lo,1
-	rcall	TFT_dive_compass_clr_label
-	; restore hi/lo
-	MOVII	divA,mpr
-	; print a dot on the middle
-	movf	lo,W
-	rcall	TFT_dive_compass_mk_print_dot
-	; finally print the right marker line
-	movlw	d'2'
-	addwf	lo,0
-;	rcall	TFT_dive_compass_mk_print_3
-;	return
-TFT_dive_compass_mk_print_3:
-	movwf	win_leftx2
-	movlw	dm_custom_compass_label_row
-	movwf	win_top
-	movlw	dm_custom_compass_label_height-.2
-	movwf	win_height
-	bra		TFT_dive_compass_mk_print_4
-TFT_dive_compass_mk_print_dot:
-	movwf	win_leftx2
-	movlw	dm_custom_compass_label_row + .9
-	movwf	win_top
-	movlw	d'4'
-	movwf	win_height
-TFT_dive_compass_mk_print_4:
-	movlw	.158
-	cpfslt	win_leftx2
-	bra		TFT_dive_compass_mk_print_5
-	movlw	d'2'
-	movwf	win_bargraph
-	movwf	win_width+0
-	clrf	win_width+1
-	movlw	color_green
-	btfss	compass_show_cardinal
-	movlw	color_red						; select color
-	BOX_COLOR									; draw box
-TFT_dive_compass_mk_print_5:
-	return
-
-TFT_dive_compass_clr_label:
-	movlw	dm_custom_compass_label_row-.2	; set top & height
-	movwf	win_top
-	movlw	dm_custom_compass_label_height+.2
-	movwf	win_height
-	rcall	TFT_dive_compass_clear
-	return
-
-TFT_dive_compass_clr_ruler:
-	; top tick
-	movlw	dm_custom_compass_tick_top_top	; set top & height
-	movwf	win_top
-	movlw	dm_custom_compass_tick_height
-	movwf	win_height
-	rcall	TFT_dive_compass_clear
-	;bottom tick
-	movlw	dm_custom_compass_tick_bot_top	; set top & height
-	movwf	win_top
-	movlw	dm_custom_compass_tick_height
-	movwf	win_height
-;	rcall	TFT_dive_compass_clear
-;	return
-TFT_dive_compass_clear:
-	; we receive RM in lo and DD in hi
-	; calculate width = RM-D
-	movf	hi,W
-	subwf	lo,W
-	bz		TFT_dive_compass_clear3		; do nothing if there is nothing to do
-	movwf	win_width+0					; RM-DD
-	movwf	win_bargraph
-	clrf	win_width+1
-	movlw	.1
-	cpfsgt	win_width+0
-	bra		TFT_dive_compass_clear3		; do not clear a single pixel (or less)
-	movff	hi,win_leftx2
-	movlw	color_black					; select color
-	BOX_COLOR								; draw box
-TFT_dive_compass_clear3:
-	return
+	return								; NO - done
+	; show bearing
+	WIN_SMALL dm_compass_bear_column,dm_compass_bear_row
+	FONT_COLOR	color_yellow			; set font color
+	MOVII	compass_bearing,mpr			; get bearing
+	goto	TFT_compass_helper			; show number and cardinal and return
 
 tft_compass_cardinal:
 	btfsc	hi,0						; heading > 255° ?
--- a/src/configuration.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/configuration.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -23,9 +23,9 @@
 ;
 #endif
 
-#define fw_version_major		.3;0x03
-#define fw_version_minor		.22;0x15
-#define fw_version_beta			0x00
+#define fw_version_major		.3
+#define fw_version_minor		.31
+#define fw_version_beta			0x01
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -42,13 +42,13 @@
 ;
 #endif
 
-#define firmware_creation_year	.24;0x18
-#define firmware_creation_month	.04;0x09
+#define firmware_creation_year	.25;0x18
+#define firmware_creation_month	.11;0x09
 #define firmware_creation_day	.24;0x06
 
-#define firmware_expire_year	.27;0x18
-#define firmware_expire_month	.01;0x08
-#define firmware_expire_day	.10;0x1C
+#define firmware_expire_year	.28;0x18
+#define firmware_expire_month	.08;0x08
+#define firmware_expire_day	.29;0x1C
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -64,7 +64,7 @@
 ;                                                                                    122.880 max. available
 #endif
 
-#define _hwos_tech_3_cR
+#define _hwos_tech_2_TR_cave
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -79,7 +79,7 @@
 ; 
 #endif
 
-#define _language_1		de
+#define _language_1		en
 #define _language_2		none
 
 
@@ -91,7 +91,7 @@
 ; _compass				compass function								mem: + 10.404 byte
 ; _helium				helium (trimix) gases and diluents				mem: +  2.113 byte || both together
 ; _ccr_pscr				CCR & pSCR modes, basic functionality			mem: +  4.117 byte ||  + 6.250 byte
-; _external_sensor		CCR & pSCR modes, external sensor support		mem: +  3.343 byte
+; _external_sensor_eccr		CCR & pSCR modes, external sensor and eccr support		mem: +  3.343 byte (OUTDATED)!
 ; _gauge_mode			gauge mode										mem: -     28 byte (less)
 ; _high_ppO2_max		raised ppO2 max limit (2.0 bar)					mem:        0 byte (neutral)
 ; _rx_functions			RX function        (OSTC TR)					mem: +  4.497 byte
@@ -124,7 +124,7 @@
 #define NOT_INCLUDED_gauge_mode
 #define NOT_INCLUDED_high_ppO2_max
 #define NOT_INCLUDED_gas_contingency
-#define NOT_INCLUDED_external_sensor
+#define NOT_INCLUDED_external_sensor_eccr
 #define NOT_INCLUDED_cave_mode
 #define NOT_INCLUDED_big_divemenu
 #define NOT_INCLUDED_firmware_recovery
@@ -144,7 +144,7 @@
 #define _gauge_mode
 #define _high_ppO2_max
 #define _gas_contingency
-#define NOT_INCLUDED_external_sensor
+#define NOT_INCLUDED_external_sensor_eccr
 #define NOT_INCLUDED_cave_mode
 #define _big_divemenu
 #define _firmware_recovery
@@ -164,7 +164,7 @@
 #define _gauge_mode
 #define _high_ppO2_max
 #define _gas_contingency
-#define NOT_INCLUDED_external_sensor
+#define NOT_INCLUDED_external_sensor_eccr
 #define _cave_mode
 #define _big_divemenu
 #define _firmware_recovery
@@ -183,13 +183,13 @@
 #define _high_ppO2_max
 #define NOT_INCLUDED_rx_functions
 #define NOT_INCLUDED_rx_update
-#define _external_sensor
+#define _external_sensor_eccr
 #define _gas_contingency
 #define NOT_INCLUDED_cave_mode
 #define _big_divemenu
 #define _firmware_recovery
 #define NOT_INCLUDED_min_depth_option
-#define _screendump
+#define NOT_INCLUDED_screendump
 
 #endif
 
@@ -203,7 +203,7 @@
 #define _high_ppO2_max
 #define NOT_INCLUDED_rx_functions
 #define NOT_INCLUDED_rx_update
-#define _external_sensor
+#define _external_sensor_eccr
 #define _gas_contingency
 #define _cave_mode
 #define _big_divemenu
@@ -222,9 +222,9 @@
 #define NOT_INCLUDED_ccr_pscr
 #define NOT_INCLUDED_gauge_mode
 #define NOT_INCLUDED_high_ppO2_max
-#define _rx_functions
-#define _rx_update
-#define NOT_INCLUDED_external_sensor
+#define NOT_INCLUDED_rx_functions
+#define NOT_INCLUDED_rx_update
+#define NOT_INCLUDED_external_sensor_eccr
 #define NOT_INCLUDED_cave_mode
 #define _big_divemenu
 #define _firmware_recovery
@@ -274,7 +274,7 @@
 #endif
 #endif
 
-#ifdef  _external_sensor
+#ifdef  _external_sensor_eccr
 #ifndef _ccr_pscr
 #define _ccr_pscr
 #endif
@@ -323,7 +323,7 @@
 #define FW_CONF_6    0x00
 #endif
 
-#ifdef _external_sensor
+#ifdef _external_sensor_eccr
 #define FW_CONF_7    0x40
 #else
 #define FW_CONF_7    0x00
--- a/src/customview.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/customview.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -59,7 +59,7 @@
 	return								;  2: not available without compass
  ENDIF
 	dcfsnz	WREG,F						;
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	goto	TFT_ppo2_sensors			;  3: ppO2 sensors
  ELSE
 	return								;  3: not available without external sensors
@@ -95,18 +95,20 @@
 	dcfsnz	WREG,F						;
 	goto	TFT_ceiling_GF_tissue		; 10: ceiling, current GF and tissues
 	dcfsnz	WREG,F						;
-	goto	TFT_CNS						; 11: CNS values
+	goto	TFT_ceiling_GF_surfGF		; 11: ceiling, current GF and Surf_GF
 	dcfsnz	WREG,F						;
-	goto	TFT_ppo2_ead_end_cns		; 12: ppO2, END/EAD and CNS / gas density
+	goto	TFT_CNS						; 12: CNS values
 	dcfsnz	WREG,F						;
-	goto	TFT_clock_batt_surfpress	; 13: clock, battery and surface pressure
+	goto	TFT_ppo2_ead_end_cns		; 13: ppO2, END/EAD and CNS / gas density
 	dcfsnz	WREG,F						;
-	return								; 14: GF factors - static only
+	goto	TFT_clock_batt_surfpress	; 14: clock, battery and surface pressure
+	dcfsnz	WREG,F						;
+	return								; 15: GF factors - static only
 	dcfsnz	WREG,F						;
  IFDEF _cave_mode
-	goto	TFT_cave_waypoints			; 15: cave waypoints
+	goto	TFT_cave_waypoints			; 16: cave waypoints
  ELSE
-	return								; 15: not available without cave mode functions
+	return								; 16: not available without cave mode functions
  ENDIF
 	return								;  0: do nothing
 
@@ -147,7 +149,7 @@
 	; prepare output of custom view title
 	WIN_BOX_BLACK .50,surf_warning1_row-1, .0, surf_decotype_column-.1	; top, bottom, left, right
 	WIN_TINY   surf_customview_title_column,surf_customview_title_row	; set title position
-	FONT_COLOR color_greenish											; set title color
+	FONT_COLOR color_green											; set title color
 
 	; jump table
 	movf	active_customview,W			; get custom view to show
@@ -257,6 +259,8 @@
 surf_customview_init_view6:
  IFDEF _compass
 	call	I2C_init_compass			; start compass
+	btfss	compass_present
+	bra		surf_customview_toggle		; not available without compass compiled in, goto next view
 	call	TFT_surface_compass_mask	; show compass mask
 	bra		surf_cv_toggle_exit			; done
  ELSE
@@ -285,7 +289,7 @@
 	; ---- view 9: sensor mV at the surface ----
 	;
 surf_customview_init_view9:
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	FLAG_ccr_mode				; in CCR mode?
 	bra		surf_customview_init_view9a	; YES - show view
 	btfsc	FLAG_pscr_mode				; NO  - in pSCR mode?
@@ -628,15 +632,17 @@
 	dcfsnz	WREG,F						;
 	bra		init_ceiling_GF_tissue		; 10: ceiling, current GF and tissues
 	dcfsnz	WREG,F						;
-	bra		init_CNS					; 11: CNS values
+	bra		init_ceiling_GF_surfGF		; 11: ceiling, current GF and surfGF
 	dcfsnz	WREG,F						;
-	bra		init_ppo2_ead_end_cns		; 12: ppO2, END/EAD and CNS/gas density
+	bra		init_CNS					; 12: CNS values
+	dcfsnz	WREG,F						;
+	bra		init_ppo2_ead_end_cns		; 13: ppO2, END/EAD and CNS/gas density
 	dcfsnz	WREG,F						;
-	bra		init_clock_batt_surfpress	; 13: clock, battery and surface pressure
+	bra		init_clock_batt_surfpress	; 14: clock, battery and surface pressure
 	dcfsnz	WREG,F						;
-	bra		init_gf_factors				; 14: GF factors
+	bra		init_gf_factors				; 15: GF factors
 	dcfsnz	WREG,F						;
-	bra		init_cave_waypoints			; 15: cave waypoints
+	bra		init_cave_waypoints			; 16: cave waypoints
 	;bra	dive_cv_toggle_exit			;  0: no view (blank screen in custom view area)
 
 dive_cv_toggle_exit:
@@ -659,6 +665,8 @@
 init_TFT_dive_compass:
  IFDEF _compass
 	call	I2C_init_compass			; start compass
+	btfss	compass_present
+	bra		dive_customview_toggle		; not available without compass compiled in, goto next view
 	call	TFT_dive_compass_mask		; mask for compass
 	bra		dive_cv_toggle_exit			; done
  ELSE
@@ -669,7 +677,7 @@
 	; ---- view 3: ppO2 sensors ---
 	;
 init_ppo2_sensors:
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	bsf		trigger_temp_changed		; fake a change of the temperature to have the resettable dive time overwritten which was shown with the compass view
 	btfsc	FLAG_ccr_mode				; in CC mode?
 	bra		init_ppo2_sensors_1			; YES
@@ -681,6 +689,8 @@
 	bra		init_ppo2_sensors_2			; YES - show this view
 	btfsc	ext_input_optical			; NO  - do we have an optical input?
 	bra		init_ppo2_sensors_2			;       YES - show this view
+	btfsc	ext_s8_full_digital			; NO - are we in external S8 full digital mode? 
+	bra		init_ppo2_sensors_2			;       YES - show this view
 	bra		dive_customview_toggle		;       NO  - goto next view
 
 init_ppo2_sensors_2:
@@ -783,8 +793,24 @@
 	call	TFT_ceiling_GF_tissue		;           - data for ceiling, current GF and tissues
 	bra		dive_cv_toggle_exit			;           - done
 
+	; ---- view 11: ceiling, tissues and surf GF
+	;
+init_ceiling_GF_surfGF:
+	btfsc	FLAG_apnoe_mode				; in apnoe mode?
+	bra		dive_customview_toggle		; YES - goto next view
+	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
+	bra		dive_customview_toggle		; YES - call next view
+	movff	char_I_model,WREG			; get model
+	iorwf	WREG					; GF enabled?
+	bnz	init_ceiling_GF_surfGF1			; YES
+	bra	dive_customview_toggle			; NO - call next view
+init_ceiling_GF_surfGF1:
+	call	TFT_ceiling_GF_surfGF_mask	;       NO  - mask for ceiling, current GF and surf GF
+	call	TFT_ceiling_GF_surfGF	    	;           - data for ceiling, current GF and surf GF
+	bra		dive_cv_toggle_exit			;           - done
+	
 
-	; ---- view 11: CNS values ----
+	; ---- view 12: CNS values ----
 	;
 init_CNS:								; CNS at end of dive
 	btfsc	FLAG_gauge_mode				; in gauge mode?
@@ -796,7 +822,7 @@
 	bra		dive_cv_toggle_exit			;           - done
 
 
-	; ---- view 12: ppO2, END/EAD and CNS/gas density ----
+	; ---- view 13: ppO2, END/EAD and CNS/gas density ----
 	;
 init_ppo2_ead_end_cns:					; 
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
@@ -808,7 +834,7 @@
 	bra		dive_cv_toggle_exit			;           - done
 
 
-	; ---- view 13: clock, battery and surface pressure
+	; ---- view 14: clock, battery and surface pressure
 	;
 init_clock_batt_surfpress:
 	call	TFT_clock_batt_surfpress_mask	; mask for clock, battery and surface pressure
@@ -816,14 +842,14 @@
 	bra		dive_cv_toggle_exit				; done
 
 
-	; ---- view 14: GF factors
+	; ---- view 15: GF factors
 	;
 init_gf_factors:
 	call	TFT_gf_factors_mask			; show GF factors
 	bra		dive_cv_toggle_exit			; done
 
 
-	; ---- view 15: cave waypoints ----
+	; ---- view 16: cave waypoints ----
 	;
 init_cave_waypoints:
  IFDEF _cave_mode
--- a/src/divemenu_tree.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/divemenu_tree.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -128,12 +128,14 @@
 
 
 main_divemenu_pscr:
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	ext_input_s8_ana			; do we have an S8/analog input (OSTC cR)?
 	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
 	btfsc	ext_input_optical			; do we have an optical input (OSTC 3)?
 	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
- ENDIF	; _external_sensor
+	btfsc	ext_s8_full_digital			; NO - are we in external S8 full digital mode? 
+	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
+ ENDIF	; _external_sensor_eccr
 
 main_divemenu_pscr_no_sensors:
 	MENU_BEGIN_DIVE	tMainMenu,  .6
@@ -145,7 +147,7 @@
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 main_divemenu_pscr_sensors:
 	MENU_BEGIN_DIVE	tMainMenu,  .6
 		MENU_CALL		tDiveBailout,		do_divemode_gaslist_bail
@@ -155,7 +157,7 @@
 		MENU_DYNAMIC	dyn_toggle_gf,		do_toggle_gf
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 
 ;-----------------------------------------------------------------------------
@@ -535,12 +537,14 @@
 	movlw	.1							; YES - revert to first menu item
 	movwf	menu_pos_cur				; set cursor position
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	ext_input_s8_ana			; do we have an S8/analog input (OSTC cR)?
 	bra		do_divemode_splist_sensor	; YES
 	btfsc	ext_input_optical			; do we have an optical input (OSTC 3)?
 	bra		do_divemode_splist_sensor	; YES
- ENDIF	; _external_sensor
+	btfsc	ext_s8_full_digital			; NO - are we in external S8 full digital mode? 
+	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
+ ENDIF	; _external_sensor_eccr
 
 do_divemode_splist_no_sensor:
 	MENU_BEGIN_DIVE	tFixedSetpoints,    .6
@@ -553,7 +557,7 @@
 	MENU_END
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 do_divemode_splist_sensor:
 	MENU_BEGIN_DIVE	tFixedSetpoints,    .6
@@ -565,7 +569,7 @@
 		MENU_CALL		tCCRModeSensor,				do_divemode_sensor
 	MENU_END
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 
 ;-----------------------------------------------------------------------------
@@ -582,7 +586,7 @@
 	decf	menu_pos_cur,W				; 1-5 -> 0-4
 	lfsr	FSR1,opt_setpoint_cbar		; load base address
 	movff	PLUSW1,char_I_const_ppO2	; set selected setpoint
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
  ENDIF
 	bcf		warn_det_sensors_lost		; clear fallback condition (revoke all sensors lost warning)
@@ -623,7 +627,7 @@
 	bra		do_exit_divemode_menu		; continue exiting the menu
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 
 ;-----------------------------------------------------------------------------
@@ -677,6 +681,8 @@
 	; check for external HUD/ppO2 Monitor
 	btfss	ext_input_optical			; do we have an optical input?
 	bra		do_switch_sp_com			; NO  - continue with common part
+	btfss	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	bra		do_switch_sp_com			; NO  - continue with common part
 	btfsc	sensor1_active				; YES - process flags from HUD/ppO2 Monitor
 	bsf		use_O2_sensor1				;     - ...
 	btfsc	sensor2_active				;     - ...
@@ -700,7 +706,7 @@
 	btg		use_O2_sensor3				; YES - toggle sensor 3 state
 	bra		do_return_divemode_sensor	; back to same menu
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
  ENDIF	; _ccr_pscr
 
 
--- a/src/divemode.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/divemode.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -81,7 +81,7 @@
 #DEFINE FLAG_TFT_depth_maximum_apnoe	TFT_output_flags_1,4	; =1: show  maximum depth of last apnoe dive
 #DEFINE FLAG_TFT_clear_apnoe_surface	TFT_output_flags_1,5	; =1: clear apnoe mode surface data from screen
 #DEFINE FLAG_TFT_apnoe_divetime			TFT_output_flags_1,6	; =1: show  apnoe mode dive times
-#DEFINE FLAG_TFT_temperature			TFT_output_flags_1,7	; =1: show  temperature (or resettable dive time when in compass view)
+#DEFINE FLAG_TFT_temperature			TFT_output_flags_1,7	; =1: show/redraw temperature
 
 ; TFT_output_flags_2 - phase 2: every second - before deco calculations, deco modes only
 #DEFINE FLAG_TFT_divemode_mask			TFT_output_flags_2,0	; =1: show  dive mode mask
@@ -242,6 +242,16 @@
 	movlw	.4					; 62,5ms * 4 = 1/4 second
 	movff	WREG,isr_tmr7_helper			; to make sure at least 1/4 will pass before trigger_quarter_second is re-set
 
+ IFDEF _compass
+	movlw	index_compass_dm			; index of compass view
+	cpfseq	active_customview			; in compass view?
+	bra		diveloop_loop_quarter_1		; NO  - continue with tasks 1/4 second
+	call	TFT_dive_compass_heading	; YES - update compass heading value
+	btfsc	compass_bearing_set			; is a bearing set?
+	call	TFT_dive_compass_extras			; YES, Update Stopwatch display in compass mode
+ ENDIF	
+	
+diveloop_loop_quarter_1: 
 	btfss	press_sensor_type			; New sensor found?
 	bra 	diveloop_loop_0				;       No - continue
 
@@ -259,15 +269,9 @@
 	bra		diveloop_loop_2				; YES - continue with tasks every 1/1 second
 	btfsc	trigger_half_second			; NO  - new 1/2 second?
 	bra		diveloop_loop_1				;       YES - continue with tasks every 1/2 second
-
+	
 	; tasks every round except every 1/1 or 1/2 second
- IFDEF _compass
-	movlw	index_compass_dm			; index of compass view
-	cpfseq	active_customview			; in compass view?
-	bra		diveloop_loop_11			; NO  - continue with tasks every round
-	call	TFT_dive_compass_heading	; YES - update compass heading value
-	bsf		FLAG_TFT_temperature		;     - redraw temperature (will show resettable dive time now)
- ENDIF
+	
 	bra		diveloop_loop_11			;     - continue tasks every round
 
 diveloop_loop_1:
@@ -349,7 +353,7 @@
 	call	check_dive_autosp			; YES - check for Auto-SP
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	FLAG_ccr_mode				; in CCR mode?
 	rcall	calc_deko_divemode_sensor	; YES - process sensor readings
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
@@ -406,6 +410,7 @@
 
 diveloop_loop_6:
 	; deco mode tasks every 1/1 second
+	INCI	divesecs_compass_trip			; increment the compass stopwatch
 	INCI	divesecs_avg_trip			; increment the resettable dive time
 	INCI	divesecs_avg_total			; increment the total      dive time
 
@@ -619,7 +624,7 @@
 	btfsc	FLAG_TFT_active_gas_divemode	; shall show active gas and dive mode?
 	call	TFT_show_active_gas_divemode	; YES - display gas, setpoint and mode
 	btfsc	FLAG_TFT_temperature			; shall show temperature?
-	call	TFT_show_temp_divemode			; YES - display temperature (or resettable dive time)
+	call	TFT_show_temp_divemode			; YES - display temperature
 
 	btfsc	FLAG_TFT_apnoe_surface_time		; shall show apnoe mode surface time?
 	call	TFT_show_apnoe_surface			; YES - show apnoe mode surface time
@@ -976,7 +981,7 @@
 
 
  IFDEF _ccr_pscr
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Process Sensor Readings
@@ -985,6 +990,8 @@
 calc_deko_divemode_sensor:
 	btfsc	ext_input_optical				; do we have an optical interface?
 	bra		calc_deko_divemode_sensor_opt	; YES - process received data
+	btfsc	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	bra		calc_deko_divemode_sensor_opt	; YES - process received data
 	btfss	ext_input_s8_ana				; NO  - do we have a S8/analog interface?
 	return									;       NO  - nothing to do, done
 	TSTOSS	opt_s8_mode						;       YES - shall use S8 interface?
@@ -1335,7 +1342,7 @@
 ;	retlw	.0								; NO  - within range
 ;	retlw	.1								; YES - out of range
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
  ENDIF	; _ccr_pscr
 
 
@@ -1887,7 +1894,7 @@
 
 divemenu_cleanup_1:
 	bsf		FLAG_TFT_active_gas_divemode; request redraw of gas/setpoint/diluent
-	bsf		FLAG_TFT_temperature		; request redraw of temperature (or resettable dive)
+	bsf		FLAG_TFT_temperature		; request redraw of temperature
 	bcf		better_gas_blinking			; stop better gas cue
 	bcf		better_dil_blinking			; stop better dil cue
 	;bra	request_redraw_NDL_deco_data; request redraw of NDL/deco data and return
@@ -2312,6 +2319,7 @@
  IFDEF _compass
 divemode_option_course:
 	MOVII	compass_heading_shown,compass_bearing
+	CLRI	divesecs_compass_trip
 	bsf		compass_bearing_set				; set flag to show heading
 	goto	menuview_toggle_reset			; terminate the pre-menu and return
  ENDIF
@@ -2358,6 +2366,7 @@
 
 	ADDLI	.300,divesecs_avg_trip			; add 5 minutes (300 seconds) to resettable time accumulator
 	ADDLI	.300,divesecs_avg_total			; add 5 minutes (300 seconds) to total time accumulator
+	ADDLI	.300,divesecs_compass_trip		; add 5 minutes (300 seconds) to compass stopwatch accumulator
 
 	MOVII	pressure_rel_cur_cached,xB		; calculate 300 x depth in mbar (300 = 5 min * 60 sec/min)
 	MOVLI	.300,xA							; ...
@@ -2849,7 +2858,7 @@
 ; Helper Function - transmit new Setpoint to external Electronics and flag Change
 ;
 xmit_sp_set_flag:
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
  ENDIF
 	bsf		event_occured				; set global   event flag
@@ -3128,10 +3137,12 @@
 	btfss	sensor3_calibrated_ok
 	bcf		use_O2_sensor3
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	; check for external HUD/ppO2 Monitor
 	btfss	ext_input_optical			; do we have an optical input?
 	bra		dive_boot_cc_part2_1		; NO
+	btfss	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	bra		dive_boot_cc_part2_1		; NO
 	btfsc	sensor1_active				; YES - process flags from HUD/ppO2 Monitor
 	bsf		use_O2_sensor1				;     - ...
 	btfsc	sensor2_active				;     - ...
@@ -3160,7 +3171,7 @@
 	movff	opt_setpoint_cbar+0,WREG	; YES - get value of setpoint 1 into WREG
 	movff	WREG,char_I_const_ppO2		; write setpoint to deco engine
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
 	goto	calc_deko_divemode_sensor	; process sensor readings and return
  ELSE
@@ -3298,6 +3309,10 @@
 	clrf	pressure_rel_accu_total+1	; ...
 	clrf	pressure_rel_accu_total+2	; ...
 	clrf	pressure_rel_accu_total+3	; ...
+	
+; IFDEF _compass	
+;	CLRI	divesecs_compass_trip		; time accumulator for the compass stopwatch (Not really needed, it's not shown until it's reset with the 1st. course set)
+; ENDIF	
 
  IFDEF _rx_functions
 
@@ -3439,7 +3454,7 @@
 	rcall	check_display_ftts			; show  fTTS time (or cave mode cTTS)
 	rcall	check_ppO2					; check ppO2
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	rcall	check_ext_sensors			; check external sensors
  ENDIF
 
@@ -4307,7 +4322,7 @@
 	goto	TFT_message_gas_needs		; show message for gas needs and return
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Check external Sensors for Loss and Divergence
@@ -4386,7 +4401,7 @@
 	incf	message_counter,F			; increase message counter
 	goto	TFT_message_divergence		; show message and return
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 
 ;=============================================================================
--- a/src/divemode.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/divemode.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -21,7 +21,7 @@
 	extern	deco_setup_cc_diluents
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	extern	calc_deko_divemode_sensor
  ENDIF
 
@@ -78,7 +78,7 @@
 #DEFINE dm_depth_col_large						.0								;   0
 #DEFINE dm_depth_bot_large						dm_depth_row_large+.61			;  75
 #DEFINE dm_depth_rgt_large						dm_depth_col_large+.59			;  59
-#DEFINE dm_depth_row_huge						.7								;   7
+#DEFINE dm_depth_row_huge						.8								;   8
 #DEFINE dm_depth_col_huge						.0								;   0
 #DEFINE dm_depth_bot_huge						dm_depth_row_huge+.90			;  97
 #DEFINE dm_depth_rgt_huge						dm_depth_col_huge+.90			;  90
@@ -304,6 +304,10 @@
 #DEFINE dm_custom_tissue_title_row				dm_customview_row+.1			; 102
 #DEFINE dm_custom_tissue_title_column			.120							; 120
 
+; Surf GF
+#DEFINE dm_custom_surfGF_title_row				dm_customview_row+.1			; 102
+#DEFINE dm_custom_surfGF_title_column			.110							; 116
+ 
 ; N2 / He values
 #DEFINE dm_custom_tissue_N2_row					dm_custom_ead_row+.5			; 122
 #DEFINE dm_custom_tissue_N2_column				.105							; 105
@@ -333,24 +337,31 @@
 
 ; Title
 #DEFINE dm_custom_compass_mask_row				dm_customview_row				; 101
-#DEFINE dm_custom_compass_mask_column			.65								;  65
+#DEFINE dm_custom_compass_mask_column			.5
 
 ; Head and arrows
-#DEFINE dm_custom_compass_head_row				dm_customview_row+.37			; 138
-#DEFINE dm_custom_compass_head_column			.62								;  62
-#DEFINE dm_custom_compass_ldir_column			.5								;   5
+#DEFINE dm_custom_compass_head_row			dm_customview_row			; 120
+#DEFINE dm_custom_compass_head_column			.75								;  62
+#DEFINE	dm_custom_compass_unit_row			dm_custom_compass_head_row+.2			; 138
+#DEFINE	dm_custom_compass_unit_column			dm_custom_compass_head_column+.36
+#DEFINE	dm_compass_bear_row				dm_customview_row+.14
+#DEFINE	dm_compass_bear_column				.20
+#DEFINE	dm_compass_stopwatch_row			dm_customview_row+.37
+#DEFINE	dm_compass_stopwatch_column			.20
+
+ #DEFINE dm_custom_compass_ldir_column			.5								;   5
 #DEFINE dm_custom_compass_rdir_column			.138							; 138
 
 ; Ruler
-#DEFINE dm_custom_compass_graph_row				dm_customview_row				; 101
-#DEFINE dm_custom_compass_graph_height			.33								;  33
-#DEFINE dm_custom_compass_tick_height			.3								;   3
-#DEFINE dm_custom_compass_tick_top_top			dm_custom_compass_graph_row+.1	; 102
-#DEFINE dm_custom_compass_tick_top_bot			dm_custom_compass_graph_row+.4	; 105
-#DEFINE dm_custom_compass_label_row				dm_custom_compass_graph_row+.6	; 107
-#DEFINE dm_custom_compass_label_height			.24								;  24
-#DEFINE dm_custom_compass_tick_bot_top			dm_custom_compass_graph_row+.30	; 131
-#DEFINE dm_custom_compass_tick_bot_bot			dm_custom_compass_graph_row+.33	; 134
+;#DEFINE dm_custom_compass_graph_row				dm_customview_row				; 101
+;#DEFINE dm_custom_compass_graph_height			.33								;  33
+;#DEFINE dm_custom_compass_tick_height			.3								;   3
+;#DEFINE dm_custom_compass_tick_top_top			dm_custom_compass_graph_row+.1	; 102
+;#DEFINE dm_custom_compass_tick_top_bot			dm_custom_compass_graph_row+.4	; 105
+;#DEFINE dm_custom_compass_label_row				dm_custom_compass_graph_row+.6	; 107
+;#DEFINE dm_custom_compass_label_height			.24								;  24
+;#DEFINE dm_custom_compass_tick_bot_top			dm_custom_compass_graph_row+.30	; 131
+;#DEFINE dm_custom_compass_tick_bot_bot			dm_custom_compass_graph_row+.33	; 134
 
 
 ;-----------------------------------------------------------------------------
--- a/src/eeprom_rs232.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/eeprom_rs232.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -14,6 +14,7 @@
 #include "shared_definitions.h"
 #include "rtc.inc"
 #include "external_flash.inc"
+#include "convert.inc"	
 
 #DEFINE INSIDE_EEPROM_RS232
 #include "eeprom_rs232.inc"
@@ -368,6 +369,7 @@
 	btfss	speed_is_normal				; speed = normal?
 	bra		enable_rs232_1				; NO  - loop waiting for ISR to have adjusted the speed
 	bsf	TRISC,7
+	btfss	aux_flag							; use Bluetooth?
 	bcf		ble_npower						; YES - switch port to comm
 	bsf		PORTJ,2						;     - /Reset (required for very old OSTC sport)
 	movlw	b'00100100'					;     - TX configuration: TX enabled, async, high speed
@@ -507,11 +509,61 @@
 
 ;-----------------------------------------------------------------------------
 
+;------------------------------------------
+; Setup BLE name to new BLE (type 2) module
+;------------------------------------------
+    global  ble2_configure_name
+ble2_configure_name:
+    btfss   dn_flag		; dn mode?
+    return			; no, return
+    ;rcall    enable_rs232
+    bcf         NCTS            ; Clear to send
+    call	wait_1s
+    call	wait_1s
+    call	wait_1s
+    call	wait_1s
+    bcf	PORTB,6
+    nop
+    bsf	PORTB,6			; rising edge -> Command mode
+    ; point to config table
+    movlw   LOW     ble_AT2
+    movwf   TBLPTRL
+    movlw   HIGH    ble_AT2
+    movwf   TBLPTRH
+    movlw   UPPER   ble_AT2
+    movwf   TBLPTRU
+    rcall   ble_init_loop
+     ; Read serial from EEPROM
+    call    eeprom_serial_number_read	; read OSTC serial number
+    movff	mpr+0, lo
+    movff	mpr+1, hi
+    lfsr	FSR2,buffer+0
+    output_65535			; lo:hi converted to ascii into POSTINC2
+    SERIAL_CC_SEND  buffer+0
+    SERIAL_CC_SEND  buffer+1
+    SERIAL_CC_SEND  buffer+2
+    SERIAL_CC_SEND  buffer+3
+    SERIAL_CC_SEND  buffer+4
+    SERIAL_LC_SEND  .13				; CR
+    WAITMS      d'200'    
+    bcf	    PORTB,6			; falling edge -> Data mode
+    movlw   LOW     ble_AT3
+    movwf   TBLPTRL
+    movlw   HIGH    ble_AT3
+    movwf   TBLPTRH
+    movlw   UPPER   ble_AT3
+    movwf   TBLPTRU
+    rcall   ble_init_loop
+    return
+    
+	
+	
 ;-----------------------------------------------------------------------------
 ; Add new services and characteristics to new BLE (type 2) module
 ;-----------------------------------------------------------------------------
     global  ble2_configure
 ble2_configure:
+    bcf		aux_flag	; needed for enable_rs232
     rcall    enable_rs232
     bcf         NCTS            ; Clear to send
     call	wait_1s
@@ -521,20 +573,33 @@
     bcf	PORTB,6
     nop
     bsf	PORTB,6			; rising edge -> Command mode
-    
+
     ; point to config table
-    movlw   LOW     ble_AT1
-    movwf   TBLPTRL
-    movlw   HIGH    ble_AT1
-    movwf   TBLPTRH
-    movlw   UPPER   ble_AT1
-    movwf   TBLPTRU
-    rcall   ble_init_loop
-	
-    rcall   disable_rs232
-    bcf	    PORTB,6	    ; keep low for min. current consumption
+    movlw	LOW     ble_AT1
+    movwf	TBLPTRL
+    movlw	HIGH    ble_AT1
+    movwf	TBLPTRH
+    movlw	UPPER   ble_AT1
+    movwf	TBLPTRU
+   
+    btfsc	dual_comm		; dual-comm hardware?
+    rcall   	ble2_configure_at4	; YES - BLE-only module in dual-comm hardware, overwrite TBLPTRx!
+    
+    rcall	ble_init_loop
+    rcall	disable_rs232
+    bcf		PORTB,6	    ; keep low for min. current consumption
     return		    ; done.
 
+ble2_configure_at4:    
+    ; point to config table
+    movlw	LOW     ble_AT4
+    movwf	TBLPTRL
+    movlw	HIGH    ble_AT4
+    movwf	TBLPTRH
+    movlw	UPPER   ble_AT4
+    movwf	TBLPTRU
+    return
+    
 ble_init_loop:
         TBLRD*+
         movlw   0xFF	; end
@@ -559,18 +624,39 @@
 	SERIAL_CC_SEND	WREG
 	bra	ble_init_loop
     
+ble_AT4:	; config table
+    ; 0xFF at the end
+    ; 0xFE: 20ms delay
+    ; 0xFD: 1s delay
+    ; .13: cr character
+    db	"AT+UBTLN=OSTC nano",.13,0xFE				; "name command"
+    ;db	"AT+UFACTORY",.13,0xFE,0xFE				; Set to factory defined configuration
+    db  "AT+UMSM=1",.13,0xFE,0xFE				; start in Data mode
+    db	"AT+UBTLE=2",.13,0xFE					; Bluetooth low energy Peripheral
+    db	"AT+UDSC=0,0",.13,0xFE,0xFE				; Disable SPS Server on ID0 (and wait 40ms)
+    db	"AT+UDSC=0,6",.13,0xFE,0xFE				; SPs Server on ID0 (and wait 40ms)
+    db	"AT+UDSC=1,0",.13,0xFE,0xFE				; Disable SPP Server on ID1 (and wait 40ms)
+    db	"AT+UDSC=1,3",.13,0xFE,0xFE				; SPP Server on ID1 (and wait 40ms)
+    db	"AT&W",.13,0xFE						; write settings into eeprom
+    db	"AT+CPWROFF",.13					; save and reboot    
+    db	0xFD, 0xFD, 0xFF
+    
 ble_AT1:	; config table
     ; 0xFF at the end
     ; 0xFE: 20ms delay
     ; 0xFD: 1s delay
     ; .13: cr character
     db	0xFD,0xFD,0xFD,0xFD					; Wait 4 seconds
-    db	"AT+UDSC=0,0",.13,0xFE,0xFE				; Disable SPP Server on ID0 (and wait 40ms)
-    db	"AT+UDSC=0,3",.13,0xFE,0xFE				; SPP Server on ID0 (and wait 40ms)
-    db	"AT+UDSC=1,0",.13,0xFE,0xFE				; Disable SPS Server on ID1 (and wait 40ms)
-    db	"AT+UDSC=1,6",.13,0xFE,0xFE				; SPS Server on ID1 (and wait 40ms)
+    db	"AT+UDSC=0,0",.13,0xFE,0xFE				; Disable SPS Server on ID0 (and wait 40ms)
+    db	"AT+UDSC=0,6",.13,0xFE,0xFE				; SPs Server on ID0 (and wait 40ms)
+    db	"AT+UDSC=1,0",.13,0xFE,0xFE				; Disable SPP Server on ID1 (and wait 40ms)
+    db	"AT+UDSC=1,3",.13,0xFE,0xFE				; SPP Server on ID1 (and wait 40ms)
     db	"AT&W",.13,0xFE						; write settings into eeprom (and wait 20ms)
     db	"AT+CPWROFF",.13,0xFD,0xFD,0xFF				; save and reboot  (and wait 2 seconds)
-
-	
+ble_AT2:	; config table
+    db	0xFD,0xFD,0xFD,0xFD					; Wait 4 seconds
+    db	"AT+UBTLN=OSTC+ ",0xFF	    				; Start of "name command"
+ble_AT3:	; config table	
+    db	"ATO1",.13,0xFF						; Enable Data mode    
+    
 	END
--- a/src/eeprom_rs232.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/eeprom_rs232.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -338,6 +338,7 @@
 	extern	disable_rs232
 	extern	rs232_wait_tx
 	extern	ble2_configure
+	extern	ble2_configure_name
 
 
  ENDIF	; INSIDE_EEPROM_RS232
--- a/src/ghostwriter.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/ghostwriter.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -94,7 +94,7 @@
 	movwf	divisor_tank				; initialize divisor
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	movlw	div_ppo2_sensors			; get divisor for ppO2 sensor
 	movwf	divisor_ppo2_sensors		; initialize divisor by default
 	btfsc	FLAG_ccr_mode				; in CCR mode?
@@ -155,7 +155,7 @@
 	movlw	infolength_gf				; YES - get length of extra data
 	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended3:
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	decfsz	divisor_ppo2_sensors,W		; check divisor if it will become 0, dump decremented value to WREG
 	bra		check_extended4				; NO  - skip
 	movlw	infolength_ppo2_sensors		; YES - get length of extra data
@@ -313,7 +313,7 @@
 	btfsc	divisor_supersat,7			; did the timer under-run?
 	clrf	divisor_supersat			; YES - reset timer
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	decfsz	divisor_ppo2_sensors,F		; decrement timer, did it became 0 ?
 	bra		store_dive_data4d			; NO  - skip
 	rcall	store_dive_ppO2_sensors		; YES - store sensor data
@@ -384,7 +384,7 @@
 	return									;     - done
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 store_dive_ppO2_sensors:
 	FLASH_CC_PROFILE sensor1_ppO2			; store sensor 1 ppO2 (in 0.01 bar steps)
 	SMOVII	sensor1_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor
@@ -763,7 +763,7 @@
 	;clrf	WREG
 	;MOVCC	WREG,header_buffer+index_decodistance
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	; store last HUD data (ISR-safe 3 byte copy)
 	SMOVTT	hud_status_byte,header_buffer+index_hud_data
  ELSE
@@ -948,7 +948,7 @@
 	FLASH_LIT_PROFILE .3						; type: ppO2 sensor data
 	FLASH_LIT_PROFILE infolength_ppo2_sensors	; get size of recording data
 	movlw	.0									; default to no ppO2 data
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	FLAG_ccr_mode						; in CCR mode?
 	movlw	div_ppo2_sensors					; YES - get sampling rate
 	btfsc	FLAG_pscr_mode						; in pSCR mode?
--- a/src/hwos.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/hwos.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -18,7 +18,7 @@
 #include "eeprom_rs232.inc"
 
 ;----------------------------- PIC Configuration -----------------------------
-;
+
 	CONFIG	RETEN   = OFF		; regulator power while in sleep mode controlled by SRETEN bit
 	CONFIG	SOSCSEL = HIGH		; high power SOSC circuit selected
 	CONFIG	XINST   = OFF		; extended instruction set disabled
@@ -46,6 +46,7 @@
 HW_descriptor					res 1		; OSTC - model descriptor (cleared & rebuilt in restart)
 HW_variants					res 1		; OSTC - model variants   (NOT cleared in restart)
 HW_variants2					res 1		; OSTC - more model variants   (NOT cleared in restart)
+HW_variants3					res 1		; OSTC - more model variants   (NOT cleared in restart)					
 						
 ;---- Flags - Hardware States
 HW_flags_state1					res 1		; hardware - states 1
@@ -105,7 +106,7 @@
 battery_type					res 1		; =0:1.5V, =1:3.6V Saft, =2:LiIon 3.7V/0.8Ah, =3:LiIon 3.7V/3.1Ah, =4: LiIon 3.7V/2.3Ah
 battery_accumulated_charge		res 2		; raw values in battery gauge IC
 battery_temperature				res 2		; battery temperature in 0.1 Kelvin
-gauge_status_byte				res 1		; gauge IC status byte
+
 
 
 
@@ -119,6 +120,7 @@
 	global	HW_descriptor
 	global	HW_variants
 	global	HW_variants2
+	global	HW_variants3
 	global	HW_flags_state1
 	global	HW_flags_state2
 	global	HW_flags_state3
@@ -151,7 +153,7 @@
 	global	battery_type
 	global	battery_accumulated_charge
 	global	battery_temperature
-	global	gauge_status_byte
+
 
 
 ;=============================================================================
@@ -342,7 +344,7 @@
 
 
 ; Timer 3 for IR-RX Timeout
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	clrf	T3GCON				; clear Timer3 gate control register
 ;	movlw	b'10001101'			; old value
 	movlw	b'10001011'			; bit 7-6: 10 = clock source SOSC/SCLKI (with bit   3 = 1)
@@ -367,6 +369,8 @@
 
 
 ; MSSP1 Module: I2C Master
+	movlw	b'00000000'			; enable slew rate control
+	movwf	SSP1STAT			; ...
 	movlw	b'00101000'			; set up I2C to master mode
 	movwf	SSP1CON1			; ...
 	clrf	SSP1CON2			; ...
@@ -410,7 +414,7 @@
 	banksel 0xF16				; addresses F16h...F5Fh are not part of the access RAM
 	movlw	b'11000000'			; disable ECCP3 and ECCP2
 	movwf	PMD0				; ...
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	movlw	b'11000001'			; disable PSP, CTMU and EMB
  ELSE
 	movlw	b'11001001'			; disable PSP, CTMU, Timer 3 and EMB
@@ -536,11 +540,12 @@
 	movwf	TBLPTRL					; ...
 	movwf	TBLPTRH					; ...
 	movwf	TBLPTRU					; ...
-	TBLRD*-							; dummy read to be in 128 byte block
 
 	movlw	b'10010100'				; setup   block erase
 	rcall	restore_write			; execute block erase
 
+	TBLRD*-							; dummy read to be in 128 byte block
+
 	; set start address in EEPROM
 	EEPROM_SET_ADDRESS eeprom_prog_page0_backup
 
--- a/src/hwos.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/hwos.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -45,7 +45,7 @@
 #DEFINE hw_logo_block			0x01E000	; color image data for heinrichs weikamp gmbh logo
 #DEFINE comm_logo_1				0x01EEDE	; color image data for USB or BT logo
 #DEFINE comm_logo_2				0x01EA04	; color image data for BT logo, "+" bootloader
-#DEFINE comm_logo_3				0x01E936	; color image data for BT logo, dn bootloader
+#DEFINE comm_logo_3				0x01EE10	; color image data for BT logo, dn bootloader
 
 
 ;-----------------------------EEPROM DATA ------------------------------------
@@ -275,8 +275,14 @@
 #DEFINE battery_show_level				.30			; [%]  threshold when to show battery level
 #DEFINE battery_warn_level_36			.15			; [%]  threshold for 3.6 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive mode
 #DEFINE battery_warn_level_15			.25			; [%]  threshold for 1.5 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive mode
-
-
+#DEFINE	battery_cycle_counter_unlock		.95			; [%]  threshold to unlock the charge cycle counter for a new charge cycle to count
+ 
+#DEFINE	rechargeable_36V_80			.3950			; [mV] fixed threshold, from UR16650ZTA.PDF, page 2, 0°C
+#DEFINE	rechargeable_36V_60			.3780			; [mV] fixed threshold, from UR16650ZTA.PDF, page 2, 0°C
+#DEFINE	rechargeable_36V_40			.3650			; [mV] fixed threshold, from UR16650ZTA.PDF, page 2, 0°C
+#DEFINE	rechargeable_36V_20			.3500			; [mV] fixed threshold, from UR16650ZTA.PDF, page 2, 0°C
+#DEFINE	rechargeable_36V_00			.3350			; [mV] fixed threshold, from UR16650ZTA.PDF, page 2, 0°C
+ 
 ; ---- 3.6 Volt Battery Sensing Data Points at 70 mA Load
 #DEFINE lithium_36v_75					.3000		; [mV]
 #DEFINE lithium_36v_50					.2900		; [mV]
@@ -292,25 +298,25 @@
 
 
 ; ---- internal Battery Gauging
-#DEFINE capacity_saft_internal			.364
-#DEFINE capacity_panasonic_internal		.121
+#DEFINE capacity_saft_internal				.364
+#DEFINE capacity_14500_internal				.121
 
 
 ; Gauge IC
 #DEFINE capacity_saft					.271		; 2.3Ah/0.085mAh/100 [%]
 #DEFINE offset_saft					.38477		; 65536-(2.3Ah/0.085mAh)
 
-#DEFINE capacity_panasonic				.94		; 0.8Ah/0.085mAh/100 [%]
-#DEFINE offset_panasonic				.56124		; 65536-(0.8Ah/0.085mAh)
-
+#DEFINE capacity_14500					.94		; 0.8Ah/0.085mAh/100 [%]
+#DEFINE offset_14500					.56124		; 65536-(0.8Ah/0.085mAh)
+ 
 #DEFINE capacity_ncr18650				.364		; 3.1Ah/0.085mAh/100 [%]
 #DEFINE offset_ncr18650					.29065		; 65536-(3.1Ah/0.085mAh)
-
+ 
 #DEFINE capacity_ur16650				.235		; 2.0Ah/0.085mAh/100 [%]
 #DEFINE offset_ur16650					.42006		; 65536-(2.0Ah/0.085mAh)
-
-#DEFINE capacity_404050					.141		; 1.2Ah/0.085mAh/100 [%]
-#DEFINE offset_404050					.51418		; 65536-(1.2Ah/0.085mAh)
+ 
+#DEFINE capacity_404050					.112		; 0.96Ah/0.085mAh/100 [%]
+#DEFINE offset_404050					.54241		; 65536-(0.96Ah/0.085mAh)
  
 ; ---- Power Consumption Values
 #DEFINE current_sleepmode				.31
@@ -326,11 +332,15 @@
 ; ---- Brightness Thresholds (between zero (off) and 255 (max. power consumption))
 #DEFINE ambient_light_max_high_36V		.170
 #DEFINE ambient_light_max_high_cr		.240
+#DEFINE ambient_light_max_high_dn		.240 
+#DEFINE ambient_no_sensor_high			.190
 #DEFINE ambient_light_max_high_15V		.100
 #DEFINE ambient_light_min_high			.35
 #DEFINE ambient_light_max_medium		.90
+#DEFINE ambient_no_sensor_medium		.50
 #DEFINE ambient_light_min_medium		.25
 #DEFINE ambient_light_max_eco			.50
+#DEFINE ambient_no_sensor_eco			.20
 #DEFINE ambient_light_min_eco			.10			; must be the lowest value!
 
 
@@ -470,10 +480,10 @@
 ;-----------------------------------------------------------------------------
 
 ;---- Hardware - OSTC Model Descriptor (stored in access RAM, cleared & rebuilt in restart, to preserve compatibility with 3rd party tools DO NOT alter bit positions)
-#DEFINE battery_gauge_available	HW_descriptor,0		; =1: OSTC has rechargeable battery with battery management chip
+#DEFINE battery_gauge_available		HW_descriptor,0		; =1: OSTC has rechargeable battery with battery management chip
 #DEFINE ambient_sensor			HW_descriptor,1		; =1: OSTC has an ambient light sensor
 #DEFINE ext_input_s8_ana		HW_descriptor,2		; =1: OSTC has S8/analog input
-#DEFINE ext_input_optical		HW_descriptor,3		; =1: OSTC has optical   input
+#DEFINE ext_input_optical		HW_descriptor,3		; =1: OSTC has optical   input or uses fully digital external interface
 #DEFINE ble_available			HW_descriptor,4		; =1: OSTC has an BT module
 #DEFINE ostc_rx_present			HW_descriptor,5		; =1: OSTC has RX module
 #DEFINE lv_core				HW_descriptor,6		; =1: OSTC has low-voltage core (2.7V)
@@ -494,11 +504,15 @@
 #DEFINE	less_io_cpu			HW_variants2,1		; =1: OSTC has a CPU with less I/O pins
 #DEFINE screen_type4			HW_variants2,2		; =1: display type 4, =0: display type 0 or 1 or 2 or 3
 #DEFINE	dn_flag				HW_variants2,3		; =1: dn
-;					HW_variants2,4		; --- unused
-;					HW_variants2,5		; --- unused
-;					HW_variants2,6		; --- unused
-;					HW_variants2,7		; --- unused
+#DEFINE screen_type5			HW_variants2,4		; =1: display type 5, =0: display type 0 or 1 or 2 or 3 or 4
+#DEFINE compass_type0			HW_variants2,5		; =1: compass type 0, =0: compass type 1 or 2
+#DEFINE compass_present			HW_variants2,6		; =1: a compass is present, =0: hardware w/o compass
+#DEFINE	battery_gauge_type		HW_variants2,7		; =1: Gauge IC LTC2959, =0: LT2942
 
+ ;---- Hardware - OSTC Model Variants3 (stored in access RAM, NOT cleared in restart)
+#DEFINE dual_comm			HW_variants3,0		; =1: dual comm hardware (USB and BLE-only)
+ 
+ 
 ;---- Hardware - States 1 (stored in access RAM, cleared on restart)
 #DEFINE analog_sw1_pressed		HW_flags_state1,0	; =1: analog switch 1 pressed
 #DEFINE analog_sw2_pressed		HW_flags_state1,1	; =1: analog switch 2 pressed
@@ -524,8 +538,8 @@
 #DEFINE	i2c_busy_pressure		HW_flags_state3,1	; =1: Currently updating pressure from MS5837
 #DEFINE	eeprom_write_error_flag		HW_flags_state3,2	; =1: an EEPROM write error occurred (Reset only in a Reboot/POR)
 #DEFINE	lock_cycle_counter		HW_flags_state3,3	; =1: Do not count charge cycle (again), cleared when batt_percent<95%
-;					HW_flags_state3,4	; --- unused
-;					HW_flags_state3,5	; --- unused
+#DEFINE	i2c_error_flag_lock		HW_flags_state3,4	; =1: The last I2C error was not displayed yet
+#DEFINE	i2c_reinit_sensor2		HW_flags_state3,5	; =1: Do an I2C reset and reinitialize the pressure sensor type 2
 ;					HW_flags_state3,6	; --- unused
 ;					HW_flags_state3,7	; --- unused
  
@@ -566,7 +580,7 @@
 #DEFINE divemode				OM_flags_mode,1		; =1: in dive mode
 #DEFINE simulatormode			OM_flags_mode,2		; =1: in simulator mode
 #DEFINE high_altitude_mode		OM_flags_mode,3		; =1: unit was manually turned on with absolute pressure < 880 mbar
-;								OM_flags_mode,4		; --- unused
+#DEFINE	ext_s8_full_digital		OM_flags_mode,4		; =1: External S8 full digital mode
 #DEFINE tr_functions_activated	OM_flags_mode,5		; =1: TR module is available and TR mode is <> off
 #DEFINE cold_start				OM_flags_mode,6		; =1: restart is entered from a cold start
  IFDEF _screendump
@@ -808,7 +822,7 @@
 #DEFINE aa_aux_flag				AA_flags,3			;     auxiliary flag for various purposes
 #DEFINE use_custom_colors		AA_flags,4			; =1: override default pixel colors, used by color_image
 #DEFINE win_invert				AA_flags,5			; =1: print in inverse video
-;								AA_flags,6			; --- unused
+#DEFINE	force_all_caps			AA_flags,6			; =1: force output all caps (even if there is a 0-9 in the string)
 ;								AA_flags,7			; --- unused
 
 
@@ -1037,6 +1051,7 @@
 	extern	HW_descriptor
 	extern	HW_variants
 	extern	HW_variants2
+	extern	HW_variants3
 
 	extern	HW_flags_state1
 	extern	HW_flags_state2
@@ -1082,7 +1097,7 @@
 	extern	battery_type
 	extern	battery_accumulated_charge
 	extern	battery_temperature
-	extern	gauge_status_byte
+
 
  endif	; ACCESS_RAM_VARS
 
@@ -1184,20 +1199,20 @@
 ;---- Battery Gauge (nAs, nC)
 battery_gauge					res 6		; 48 bit -> 78 Ah max
 
-;---- IR/S8-Link
-ir_s8_buffer					res .18		; buffer for data received on IR/S8 interface,
-											; also used to buffer MS5541 raw calibration data
-
- IFDEF _external_sensor
+;---- MS5541 raw calibration data
+ms5541_rawdata					res 8
+					
+ IFDEF _external_sensor_eccr
 ir_s8_counter					res 1
 ir_s8_timeout					res 1		; timeout for valid data
  ENDIF
 
 ;---- raw O2 Sensor Data received on S8 Link
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 s8_rawdata_sensor1				res 3		; 24 bit A/D raw data from S8 HUD sensor 1
 s8_rawdata_sensor2				res 3		; 24 bit A/D raw data from S8 HUD sensor 2
 s8_rawdata_sensor3				res 3		; 24 bit A/D raw data from S8 HUD sensor 3
+ccr_status_byte					res 2		; Status bytes for ccr				
  ENDIF
 
 ;---- Switch Processing (8 byte, called by ISR and sleep mode)
@@ -1218,7 +1233,7 @@
 debounce_counter			res 1		; multiples of 16ms 
 isr_tmr7_helper				res 1		; used for 1/4 second trigger
 			
-; 158 byte used, 2 byte free
+; 150 byte used, 10 byte free
 
 
 ;-----------------------------------------------------------------------------
@@ -1310,6 +1325,7 @@
 ;---- Dive Mode / all modes (26 byte)
 divesecs_avg_trip				res 2		; time accumulator for the resettable average depth & stopwatch
 divesecs_avg_total				res 2		; time accumulator for the total dive average depth
+divesecs_compass_trip				res 2		; time accumulator for the compass stopwatch
 pressure_rel_avg_trip			res 2		; calculated resettable average depth
 pressure_rel_avg_total			res 2		; calculated total dive average depth
 pressure_rel_cur_cached			res 2		; cached current relative pressure
@@ -1464,7 +1480,9 @@
 pressure_update_lag_counter		res 1		; lag time counter for fast surface pressure display updating
 gp_debug				res 2		; General Purpose debug registers
 
-; 204 byte used, 4 byte free (208 byte total)
+gauge_status_byte				res 1		; gauge IC status byte
+				
+; 208 byte used, 1 byte free (208 byte total)
 
 
 ;-----------------------------------------------------------------------------
@@ -1518,7 +1536,7 @@
 supersat_start					res 1		; leading tissue supersaturation at beginning of the dive
 
 ;---- O2 Sensors (9 byte, updated by ISR when sensors are connected via datalink)
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 sensor1_mv						res 2		; sensor 1 voltage in 0.1  mV  steps
 sensor2_mv						res 2		; sensor 2 voltage in 0.1  mV  steps
 sensor3_mv						res 2		; sensor 3 voltage in 0.1  mV  steps
@@ -1596,13 +1614,18 @@
 time_last_2nd					res 2		; last pressure reading time       in seconds    |
  ENDIF
 
-i2c_error_vault					res 2		; Store last used device ID and data byte
+i2c_error_vault					res 3		; Store last used device ID, data byte and copy of SSP1CON2
 D1_buffer					res 3		; Buffer of D1 (Sensor raw data)
 D2_buffer					res 3		; Buffer of D2 (Sensor raw data)					
-
+i2c_error_counter				res 2		; counts I2C errors
+					
 brightness					res 1		; =0: Eco, =1:Medium, =2:Full
 charge_cycles					res 2		; 16bit charge cycles counter
-; 159 byte used, 90 byte free
+					
+;---- IR/S8-Link
+ir_s8_buffer					res .64		; buffer for data received on IR/S8 interface,
+
+; 224 byte used, 25 byte free
 
 
 ;-----------------------------------------------------------------------------
@@ -1729,6 +1752,7 @@
 opt_conservatism				res 1		; unused dummy option for compatibility with 3rd party tools
 opt_warning_level_divemode			res 1		; warning verbose level (divemode) =0: Less, =1: All				
 opt_timeformat					res 1		; =0:24h, =1:12h
+opt_BLE_compatibility				res 1		; =1: configure BLE name to hwOS style for dn hardware					
 					
 ;---- RX Function Settings
 opt_transmitter_id_1			res 2		; 16 bit transmitter ID for Gas 1
--- a/src/i2c.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/i2c.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -42,6 +42,11 @@
 ;   -------------
 ;   LTC2942 read address  (8-Bit): 0xC9   
 ;   LTC2942 write address (8-Bit): 0xC8 
+;    
+;   Alternative Battery gauge    
+;   -------------
+;   LTC2959 read address  (8-Bit): 0xC7   
+;   LTC2959 write address (8-Bit): 0xC6 
 ;
 ;   Alternative pressure sensor
 ;   -----------
@@ -120,15 +125,12 @@
 	;bra	I2C_RX_accelerometer_compass0	; NO  - compass0 then
 
 ;I2C_RX_accelerometer_compass0:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x38						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x00						; ??
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x39						; address
 	rcall	I2C_TX						; send byte
 	rcall	I2C_OneByteRX				; get  status byte
@@ -170,9 +172,7 @@
 
 	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; copy data byte to hi
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
-	; according to data sheet there should be no master acknowledge for the last byte (accel_DZ+0)...
+	rcall	I2C_OneByteRX_NACK			; receive last byte with not acknowledge
 	movff	SSP1BUF,lo					; copy data byte to lo
 	rcall	I2C_TwoBytesRX_div16_2		; divide hi:lo/16 (signed)
 	comf	hi							; 16 bit sign change
@@ -180,21 +180,16 @@
 	btfsc	STATUS,C					; carry to propagate?
 	incf	hi,F						; YES - do it
 	MOVII	mpr,accel_DZ				; copy result to accel_DZ
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall		WaitMSSP				; wait for TX to complete
-	return
+	bra	I2C_PEN						; stop condition
 
 
 I2C_RX_accelerometer_compass1:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	b'10101000'					; 0x28 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x3D						; address
 
 I2C_RX_accelerometer_common:			; common part for compass 1,2 and 3
@@ -260,12 +255,9 @@
 	MOVII	mpr,accel_DY				; copy result
 	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; accel_DZ+0
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
-	; according to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)...
+	rcall	I2C_OneByteRX_NACK			; receive last byte with not acknowledge
 	movff	SSP1BUF,hi					; accel_DZ+1
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
 	comf	hi							; 16 bit sign change for Z
 	negf	lo							; ...
@@ -276,41 +268,26 @@
 
 
 I2C_RX_accelerometer_compass2:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x32						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	b'10101000'					; 0x28 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x33						; address
 	bra		I2C_RX_accelerometer_common	; continue with common part
 
 I2C_RX_accelerometer_compass3:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3A						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x28						; 0x28 (OUT_X_L_A)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x3B						; address
 	bra		I2C_RX_accelerometer_common	; continue with common part
 
 
-;-----------------------------------------------------------------------------
-; Helper Function - receive 1 Byte with Acknowledge
-;
-I2C_OneByteRX:
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf		SSP1CON2,ACKEN				; send master acknowledge
-	bra		WaitMSSP					; wait for TX to complete and return
-
 
 ;-----------------------------------------------------------------------------
 ; Read Compass
@@ -328,18 +305,14 @@
 	;bra	I2C_RX_compass0				; NO  - compass 0 then
 
 ;I2C_RX_compass0:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
-	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
+	rcall	I2C_SEN						; start condition
+	movlw	0x3C						; address + write bit
 	rcall	I2C_TX						; send byte
-	movlw	0x03						; ??
+	movlw	0x03						; Point to Data Output X MSB Register (0x03)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
-	movlw	0x3D						; address
+	rcall	I2C_PEN						; stop condition
+	rcall	I2C_SEN						; start condition
+	movlw	0x3D						; address + read bit
 	rcall	I2C_TX						; send byte
 
 	; Compass IC sends data in following order:
@@ -383,11 +356,9 @@
 	movff	SSP1BUF,compass_DZ+0		; data byte
 	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,compass_DX+1		; data byte
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,compass_DX+0		; data byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	btfss	flip_screen					; 180° rotation?
 	return								; NO  - done
 	banksel	compass_DX					; YES - flip X
@@ -400,15 +371,12 @@
 
 
 I2C_RX_compass1:						; compass type 1
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	b'10001000'					; 0x08 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x3D						; address
 	rcall	I2C_TX						; send byte
 	;rcall	WaitMSSP					; TODO needed? (mH)
@@ -444,27 +412,21 @@
 I2C_RX_compass1_2:
 	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_OneByteRX_NACK			; receive last byte with not acknowledge
 	movff	SSP1BUF,hi					; data byte
 	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
 	MOVII	mpr,compass_DZ				; copy result
-	bsf	SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
-	return								; done
+	bra	I2C_PEN						; stop condition
 
 
 
 I2C_RX_compass2:						; compass type 2
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0xE8						; 0x68 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x3D						; address
 	rcall	I2C_TX						; send byte
 I2C_RX_compass2_xx:						; compass 3 joins in here
@@ -499,26 +461,21 @@
 	MOVII	mpr,compass_DY
 	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
+	rcall	I2C_OneByteRX_NACK			; receive last byte with not acknowledge
 	movff	SSP1BUF,hi					; data byte
 ;	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
 	MOVII	mpr,compass_DZ				; copy result
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					
-	return								; done
+	bra	I2C_PEN						; stop condition
 
 
 
 I2C_RX_compass3:						; compass type 3
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0xA8						; 0x28 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0x3D						; address
 	rcall	I2C_TX						; send byte
 	bra		I2C_RX_compass2_xx			; join with compass 2 code
@@ -531,73 +488,85 @@
 ;
 	global	I2C_init_compass
 I2C_init_compass:
+	bsf		compass_present				; Set global compass flag
 	bsf		compass_enabled				; flag compass will be enabled
 	bcf		compass_type2				; clear in preparation of chip detection
 	bcf		compass_type3				; ...
 
 	; probe for compass 3
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3A						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	movwf	SSP1BUF						; control byte
 	rcall	WaitMSSP					; wait for TX to complete
+	; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
 	btfss	SSP1CON2,ACKSTAT			; ACK received?
 	bsf		compass_type3				; YES - ACK was send, compass 3 found
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	btfsc	compass_type3				; compass 3 found?
 	bra		I2C_init_compass3			; YES - initialize compass 3
 
 	; probe for compass 2
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x32						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	movwf	SSP1BUF						; control byte
 	rcall	WaitMSSP					; wait for TX to complete
-	btfss	SSP1CON2,ACKSTAT			; ACK received?
+	; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
+        btfss	SSP1CON2,ACKSTAT			; ACK received?
 	bsf		compass_type2				; YES - ACK send, compass 2 found
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	btfsc	compass_type2				; compass 2 found?
 	bra		I2C_init_compass2			; YES - initialize compass 2
 
-	; probe for compass 0 or 1
+	; probe for compass 1
 	bsf		compass_type1				; assume compass 1 by default
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x0F						; ??
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
+	rcall	I2C_SEN						; start condition
 	movlw	0x3D						; address
 	rcall	I2C_TX						; send byte
 	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movlw	0x49						; 0x49 = compass 1
 	cpfseq	SSP1BUF						; 0x49 received?
 	bcf		compass_type1				; NO - clear flag for compass 1
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	btfsc	compass_type1				; compass 1 found?
 	bra		I2C_init_compass1			; YES - initialize compass 1
-	;bra	I2C_init_compass0			; NO  - must be compass 0 then
+	
+	; probe for compass 0
+	bsf	compass_type0					; assume compass 0 by default
+	rcall	I2C_SEN						; start condition
+	movlw	0x3C						; address + write bit
+	rcall	I2C_TX						; send byte
+	movlw	0x0A						; Point to Identification Register A
+	rcall	I2C_TX						; send byte
+	rcall	I2C_PEN						; stop condition
+	rcall	I2C_SEN						; start condition
+	movlw	0x3D						; address + read bit
+	rcall	I2C_TX						; send byte
+	rcall	I2C_OneByteRX					; receive 1 byte with acknowledge
+	movlw	b'01001000'					; Identification Register A must be "H"
+	cpfseq	SSP1BUF						; Compare with received value
+	bcf	compass_type0					; Not equal -> Not compass 0
+	rcall	I2C_PEN						; stop condition
+	
+	btfsc	compass_type0				; compass 0 found?
+	bra	I2C_init_compass0			; YES - initialize compass 0
+;	; no compass of any type found
+	bcf	compass_present				; Delete global compass flag
+	return
 
 
 I2C_init_compass0:
 	; magnetic
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x00						; ??
 	rcall	I2C_TX						; send byte
@@ -612,25 +581,20 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; select continuous mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	; accelerometer
 	rcall	I2C_sleep_accelerometer0	; registers can only be changed in standby mode
 
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x38						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x0E						; XYZ_DATA_CFG
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; high pass filter = 0, +/- 2 g range
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
+	rcall	I2C_SEN						; start condition
 	movlw	0x38						; address
 	rcall	I2C_TX						; send byte
 	movlw	0x2A						; CTRL_REG1
@@ -640,11 +604,9 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000010'					; CTRL_REG2: high-res in active mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x38						; address
 	rcall	I2C_TX						; send byte
 	movlw	0x2A						; CTRL_REG1
@@ -652,17 +614,13 @@
 ;	movlw	b'00110001'					; CTRL_REG1: 160 ms data rate, active  mode
 	movlw	b'00110101'					; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
 
 
 
 I2C_init_compass1:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x9F						; 1F with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
@@ -697,19 +655,15 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL7 Continuous Mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
 
 	; accelerometer initializes along with magnetic sensor
 
 
 I2C_init_compass2:
 	; magnetic
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0xE0						; 0x60 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
@@ -719,14 +673,11 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00010000'					; CFG_REG_C_M BDU=1 0x62 0x57
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	; accelerometer
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x32						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x9F						; 1F with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
@@ -742,17 +693,13 @@
 	rcall	I2C_TX						; send byte
 ;	movlw	b'00000000'					; CTRL_REG5_A
 ;	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
 
 
 I2C_init_compass3:
 	; magnetic
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0xA0						; 0x20 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
@@ -768,14 +715,11 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG5_M 0x24
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	;accelerometer
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3A						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x20
 	rcall	I2C_TX						; send byte
@@ -787,18 +731,10 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'11001100'					; CTRL_REG4_A 0x23
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
+	
 
-;-----------------------------------------------------------------------------
-; Helper Function - send 1 Byte, wait for end of transmission and check ackn
-;
-I2C_TX:
-	movwf	SSP1BUF						; put byte to be sent into TX buffer
-	rcall	WaitMSSP					; wait for TX to complete
-	bra		I2C_Check_ACK				; check for acknowledge by receiver and return
-
+	
 ;-----------------------------------------------------------------------------
 ; Deactivate Compass / Accelerometer
 ;
@@ -818,10 +754,8 @@
 
 I2C_sleep_compass0:
 	; magnetic
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x00						; ??
 	rcall	I2C_TX						; send byte
@@ -831,58 +765,45 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000010'					; idle mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 I2C_sleep_accelerometer0:
 	; accelerometer
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x38						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x2A						; CTRL_REG1
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; standby mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
 
 
 I2C_sleep_compass1:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x20						; CTRL_REG1
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; data for CTRL_REG1: acceleration sensor power-down mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
 	rcall	I2C_TX						; send byte
 	movlw	0x26						; CTRL_REG7
 	rcall	I2C_TX						; send byte
 	movlw	b'00000010'					; data for CTRL_REG7: magnetic sensor power-down mode
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
 
 	; accelerometer sleeps with magnetic sensor
 
 
 I2C_sleep_compass2:
 	; magnetic
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0xE0						; 0x60 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
@@ -894,14 +815,11 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; INT_CTRL_REG_M 0x63
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	; accelerometer
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x32						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x9F						; 1F with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
@@ -909,45 +827,121 @@
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG1_A     0x20 (all off)
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
 
 
 I2C_sleep_compass3:
 	; magnetic
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3C						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0xA2						; 0x22 with auto-increment (MSB=1)
 	rcall	I2C_TX						; send byte
 	movlw	b'01000010'					; CTRL_REG3_M (power-down) 0x22
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 
 	; accelerometer
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x3A						; address
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x20
 	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20
 	rcall	I2C_TX						; send byte
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	bra	I2C_PEN						; stop condition
+	
+	
+;-----------------------------------------------------------------------------
+; Helper Function - receive 1 Byte with Not-Acknowledge
+;
+I2C_OneByteRX_NACK:
+	rcall	I2C_RCEN					; enable receive mode
+	bsf	SSP1CON2,ACKDT					; set ACKDT flag
+	rcall	I2C_ACKEN					; send master acknowledge
+	bcf	SSP1CON2,ACKDT					; reset ACKDT flag
+	return
 
 
 ;-----------------------------------------------------------------------------
+; Helper Function - receive 1 Byte with Acknowledge
+;
+I2C_OneByteRX:
+	rcall	I2C_RCEN					; enable receive mode
+	bra	I2C_ACKEN					; send master acknowledge
+	
+;-----------------------------------------------------------------------------
+; Helper Function - send 1 Byte, wait for end of transmission and check ackn
+; add WREG to checksum byte first
+I2C_TX_CHKSUM:
+	addwf	sub_a+0,F					; add to checksum
+;	bra	I2C_TX
+;-----------------------------------------------------------------------------
+; Helper Function - send 1 Byte, wait for end of transmission and check ackn
+;
+I2C_TX:
+	movwf	SSP1BUF						; put byte to be sent into TX buffer
+	btfss	i2c_error_flag_lock				; vault in use already?
+	movff	WREG,i2c_error_vault+0				; NO, Store address	
+	rcall	WaitMSSP					; wait for TX to complete
+	bra		I2C_Check_ACK				; check for acknowledge by receiver and return
+
+	
+;-----------------------------------------------------------------------------
+; Helper Function - I2C Start Condition
+;
+I2C_SEN:
+	bsf	SSP1CON2,SEN					; start condition
+	bra	WaitMSSP					; wait for TX to complete (And return)
+
+;-----------------------------------------------------------------------------
+; Helper Function - I2C Repeated Start Condition
+;
+I2C_RSEN:
+	bsf	SSP1CON2,RSEN					; repeated start condition
+	bra	WaitMSSP					; wait for TX to complete (And return)
+	
+
+;-----------------------------------------------------------------------------
+; Helper Function - I2C Stop Condition
+;
+I2C_PEN:
+	bsf	SSP1CON2,PEN					; stop condition
+	rcall	WaitMSSP					; wait for TX to complete (And return)
+I2C_WAIT_100US:	
+	; add ~100µs bus free time (min. 66µs recommended for LTC2959)
+	; Remark: not exact: 122µs +/- 30.5 µs + worst case ISR latency
+	setf	TMR5H						; initialize timer 5, high byte first
+	movlw	.255-.4						; 4 x 31.5 µs = 126µs, min: 94,5µs
+	movwf	TMR5L						; initialize timer 5, low  byte thereafter
+	bcf	PIR5,TMR5IF					; clear timer 5 overrun flag
+I2C_PEN_Loop:
+	btfss	PIR5,TMR5IF					; did timer 5 overrun?
+	bra	I2C_PEN_Loop					; NO  - repeat inner loop
+	return
+
+;-----------------------------------------------------------------------------
+; Helper Function - Master Acknowledge	
+;
+I2C_ACKEN:
+	bsf	SSP1CON2,ACKEN					; master acknowledge	
+	bra	WaitMSSP					; wait for TX to complete (And return)
+
+;-----------------------------------------------------------------------------
+; Helper Function - Enable reeive mode
+;
+I2C_RCEN:
+    	bsf	SSP1CON2,RCEN					; enable receive mode
+	bra	WaitMSSP					; wait for TX to complete (And return)
+	
+;-----------------------------------------------------------------------------
 ; Helper Function - wait for TX to complete
 ;
 WaitMSSP:
-	movff	SSP1BUF,i2c_error_vault+1
+        btfss	i2c_error_flag_lock				; vault in use already?
+	movff	SSP1BUF,i2c_error_vault+1			; NO, store value
+	btfss	i2c_error_flag_lock				; vault in use already?
+	movff	SSP1CON2,i2c_error_vault+2			; NO, store value
 	clrf	i2c_temp1					; wait for max 256 loops
 WaitMSSP_loop:
 	decfsz	i2c_temp1,F					; decrement loop counter, timeout?
@@ -965,12 +959,10 @@
 ;
 I2C_MasterNotAckStop:
 	bsf		SSP1CON2,ACKDT				; set ACKDT flag
-	bsf		SSP1CON2,ACKEN				; master NOT acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master NOT acknowledge
 	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
 
-	bsf	SSP1CON2,PEN					; stop condition
-	bra	WaitMSSP					; wait for TX to complete
+	bra	I2C_PEN						; stop condition
 	
 ;-----------------------------------------------------------------------------
 ; Helper Function - check for Acknowledge by Receiver
@@ -989,6 +981,7 @@
 	rcall	I2CReset					; reset I2C
 	bcf		PIR1,SSP1IF					; clear TX completion flag
 	bsf		i2c_error_flag				; set error flag
+	bsf		i2c_error_flag_lock			; lock the error vault
 	bcf		active_reset_ostc_rx		; release reset from RX circuitry
 ;	bcf	i2c_busy_temperature
 ;	bcf	i2c_busy_pressure
@@ -1000,6 +993,7 @@
 ;
 ; recover in case something went wrong, i.g. slave holds SDA low
 ;
+	global	I2CReset
 I2CReset:
 	clrf	SSP1CON1					; reset entire module
 	clrf	SSP1CON2					; ...
@@ -1028,7 +1022,7 @@
 I2CReset_2:
 	bsf		TRISC,3						; SCL as input
 	clrf	SSP1CON1					; setup I2C mode
-	WAITMS	d'10'						; wait 10 ms (reset-timeout for I2C devices)
+	rcall	I2C_WAIT_100US					; ISR-Safe 100µs wait
 	movlw	b'00000000'					; enable slew rate control
 	movwf	SSP1STAT					; ...
 	movlw	b'00101000'					; configure I2C module
@@ -1037,13 +1031,30 @@
 	movwf	SSP1CON2					; ...
 	movlw	i2c_speed_value
 	movwf	SSP1ADD						; ...
-	return								; done
+	rcall	I2C_WAIT_100US					; ISR-Safe 100µs wait
+	movlw	.1
+	addwf	i2c_error_counter+0
+	movlw	.0
+	addwfc	i2c_error_counter+1				; +1 on the error counter
+	btfss	press_sensor_type				; =1: pressure sensor MS5837, =0: Pressure sensor MS5541
+	return							; MS5541, Done.
+	; reset the sensor
+	rcall	I2C_SEN						; start condition
+	movlw	0xEC						; address byte + write bit
+	rcall	I2C_TX						; send byte
+	movlw	0x1E
+	rcall	I2C_TX						; send byte
+	rcall	I2C_PEN						; stop condition
+	WAITMS	.5						; 2.8ms according to datasheet
+	return							; done
 
 
 ;-----------------------------------------------------------------------------
 ; Helper Function - Initialize Gauge IC again after an UVLO Event
 ;
-lt2942_init_again:
+battery_gauge_init_again:
+	btfsc	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	return
 	rcall   I2CReset
 	movlw	0x02									; point to accumulated charge registers
 	rcall	I2C_TX_GAUGE							; send byte to the LT2942 gauge IC
@@ -1053,78 +1064,76 @@
 	movff	battery_accumulated_charge+0,SSP1BUF	; data byte
 	rcall	WaitMSSP								; wait for TX to complete
 	rcall	I2C_Check_ACK							; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN							; stop condition
-	rcall	WaitMSSP								; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	MOVII	battery_accumulated_charge,sub_a		; copy result to sub_a
-	;bra	lt2942_init								; and initialize again...
+	;bra	battery_gauge_init								; and initialize again...
 
 
 ;-----------------------------------------------------------------------------
 ; Initialize Gauge IC
 ;
-	global	lt2942_init
-lt2942_init:
-	movlw	0x01						; point to control reg B
-	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
-	movlw	b'11111000'					; automatic conversion every two seconds
-	movwf	SSP1BUF				    ; data byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
-
-;-----------------------------------------------------------------------------
-; Sleep Gauge IC
-;
-	global	lt2942_sleep
-lt2942_sleep:
-	movlw	0x01						; point to control reg B
-	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
-	movlw	b'00111000'					; sleep
-	movwf	SSP1BUF				    ; data byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	global	battery_gauge_init
+battery_gauge_init:
+	movlw	0x01						; point to control reg B / ADC Control
+	rcall	I2C_TX_GAUGE					; send byte to the gauge IC
+	movlw	b'11111000'					; automatic conversion every two seconds (LT2942)
+	btfsc	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	movlw	b'00111000'					; ADC Mode to "Smart Sleep" (converts V, I, T every 52 seconds (tolerance < ±5%)) (LTC2959)
+	rcall	I2C_TX						; send byte
+	btfsc	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	movlw	b'01010000'					; 20µV deadband
+	btfsc	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	rcall	I2C_TX						; send one byte more for the LTC2959
+	bra	I2C_PEN						; stop condition
 
 ;-----------------------------------------------------------------------------
 ; Read Gauge IC - Status Register
 ;
 	global	lt2942_get_status
 lt2942_get_status:
-	bcf		battery_gauge_available		; clear flag
-	movlw	0x00						; point to status register
-	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
-	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
+	bcf	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	bcf	battery_gauge_available				; clear flag on default
 
-	bsf		SSP1CON2,ACKDT				; set ACKDT flag
-	bsf		SSP1CON2,ACKEN				; master NOT acknowledge
+	; try LTC2942
+	rcall	I2C_SEN						; start condition
+	movlw	0xC8						; address byte + Write bit
+	movwf	SSP1BUF						; put byte to be sent into TX buffer
 	rcall	WaitMSSP					; wait for TX to complete
-	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
-
-	movff	SSP1BUF,WREG				; copy received byte to WREG
-	btfss	WREG,7						; 2942 found?
-	bsf		battery_gauge_available		; YES - set flag
-	bsf		SSP1CON2,PEN				; stop condition
+	; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
+	btfss	SSP1CON2,ACKSTAT				; ACK received from slave?
+	bsf	battery_gauge_available				; YES - set flag
+	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
+	btfsc	battery_gauge_available				; found?
+	return							; YES - done
+	
+	; try LTC2959
+	rcall	I2C_SEN						; start condition
+	movlw	0xC6						; address byte + Write bit
+	movwf	SSP1BUF						; put byte to be sent into TX buffer
 	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
-
+	; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
+	btfss	SSP1CON2,ACKSTAT				; ACK received from slave?
+	bsf	battery_gauge_available				; YES - set flag
+	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
+	btfsc	battery_gauge_available				; found?
+	bsf	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	return							; NO, return
 
 ;-----------------------------------------------------------------------------
 ; Read Gauge IC - Voltage
 ;
 	global	lt2942_get_voltage
 lt2942_get_voltage:
+  
+	btfsc	battery_gauge_type			; =1: Gauge IC LTC2959, =0: LT2942
+	bra	LTC2959_get_voltage			; use new IC
+	
 	movlw	0x08						; point to voltage registers
 	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
 	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 	movff	SSP1BUF,xA+1				; copy received byte to xA+1
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,xA+0				; copy received byte to xA+0
 	
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
@@ -1133,12 +1142,46 @@
 	MOVLI	.6000,xB					; load conversion multiplicand into xB
 	call	mult16x16					; xC = xA * xB -> multiply raw value in xA with conversion multiplicand
 										; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 %
-	movff	xC+2,batt_voltage+0			; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
-	movff	xC+3,batt_voltage+1			; ...
+	movff	xC+2,xC+0			; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
+	movff	xC+3,xC+1			; use xC+0 and xC+1 as temp
 
-	tstfsz	batt_voltage+1				; < 256 mV ?
-	return						; NO  - done
-	bra	lt2942_init_again			; YES - initialize gauge and return
+	movlw	.4					; battery voltage < 4*256mV (1.024)?
+	cpfslt	xC+1					; < 1024 mV ?
+	bra	lt2942_get_voltage_check_high		; NO  - Continue checking
+	bra	battery_gauge_init_again			; YES - initialize gauge and return (and leave batt_voltage:2 untouched)
+	
+lt2942_get_voltage_check_high:
+    	movlw	.17					; battery voltage >= 17*256mV (4.352V)?
+	cpfslt	xC+1					;     - ... ?
+	bra	battery_gauge_init_again			; YES - initialize gauge and return (and leave batt_voltage:2 untouched)
+	; NO  - done
+	movff	xC+0, batt_voltage+0
+	movff	xC+1, batt_voltage+1
+	bra	lt2942_get_accumulated_charge	;     - read coulomb counter (And return)
+	
+LTC2959_get_voltage:
+	movlw	0x0F						; point to voltage registers
+	rcall	I2C_TX_GAUGE				; send    byte to   the gauge IC
+	rcall	I2C_RX_GAUGE				; receive byte from the Gauge IC
+	rcall	I2C_ACKEN					; send master acknowledge
+	movff	SSP1BUF,xA+1				; copy received byte to xA+1
+	rcall	I2C_RCEN					; enable receive mode
+	movff	SSP1BUF,xA+0				; copy received byte to xA+0
+	
+	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
+	
+	; convert voltage from raw value to mV
+	MOVLI	.62600,xB					; load conversion multiplicand into xB
+	call	mult16x16					; xC = xA * xB -> multiply raw value in xA with conversion multiplicand
+										; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 %
+	;movff	xC+2,xC+0			; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
+	;movff	xC+3,xC+1			; use xC+0 and xC+1 as temp
+
+	movff	xC+2, batt_voltage+0
+	movff	xC+3, batt_voltage+1
+	rcall	lt2942_get_accumulated_charge	;     - read coulomb counter (And return)
+
+	return								; done
 
 
 ;-----------------------------------------------------------------------------
@@ -1146,24 +1189,26 @@
 ;
 	global	lt2942_get_temperature
 lt2942_get_temperature:					; read battery temperature
+    	btfsc	battery_gauge_type			; =1: Gauge IC LTC2959, =0: LT2942
+	bra	LTC2959_get_temperature
+
 	movlw	0x0C						; point to temperature register
 	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
 	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 	movff	SSP1BUF,xA+1				; store raw temperature, high byte
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,xA+0				; store raw temperature, low byte
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 
-	; convert temperature from raw value to Kelvin
+	; convert temperature from raw value to Kelvin in 0.1K
 	MOVLI	.6000,xB					; load conversion multiplicand into xB
 	call	mult16x16					; xC = xA * xB -> multiply raw value in xA with conversion multiplicand
 										; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 %
 	movff	xC+2,battery_temperature+0	; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
 	movff	xC+3,battery_temperature+1	; ...
 
+lt2942_get_temperature_common:	
 	; check if battery is being charged right now
 	btfss	cc_active					; in CC charging mode?
 	return								; NO  - not charging, done
@@ -1189,43 +1234,43 @@
 	bsf		charge_disable				;     - set      charging-inhibit signal
 	bcf		charge_enable				;     - activate charging-inhibit signal
 	bsf		battery_overtemp			;     - flag that the battery charging over-temperature protection has tripped
-	return								;     - done
+	return							;     - done
 
+LTC2959_get_temperature:	
+	return
+    
 
 ;-----------------------------------------------------------------------------
 ; Read Gauge IC - Read State of Charge
 ;
-	global	lt2942_get_accumulated_charge
 lt2942_get_accumulated_charge:			; read accumulated charge and compute percent
+    	btfsc	battery_gauge_type			; =1: Gauge IC LTC2959, =0: LTC2942
+	bra	LTC2959_get_accumulated_charge
+    
+	; old LTC2942
 	movlw	0x00						; point to status register
 	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
 	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 	movff	SSP1BUF,gauge_status_byte	; copy received byte to gauge_status_byte
 
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete					; dummy read (control byte)
-	movf	SSP1BUF,W					; dump to WREG
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
+	movf	SSP1BUF,W					; dump to WREG (Control)
+	rcall	I2C_ACKEN					; send master acknowledge
 
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,sub_a+1				; copy received byte to sub_a+1
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,sub_a+0				; copy received byte to sub_a+0
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 
+lt2942_get_accumulated_charge2:	
 	btfsc	gauge_status_byte,0			; UVLO event ?
-	rcall	lt2942_init_again			; YES - do an re-initialization
+	rcall	battery_gauge_init_again			; YES - do an re-initialization
 	MOVII	sub_a,battery_accumulated_charge	; save raw value
-
-	; Compute batt_percent = (charge - battery_offset) / 365
+	; Compute batt_percent = (charge - battery_offset) / capacity_xxxxxx
 	MOVII	battery_offset,sub_b		; get battery offset
 	call	subU16						; sub_c = sub_a - sub_b (with signed values)
 	clrf	batt_percent				; default batt_percent to zero
@@ -1240,12 +1285,64 @@
 	movlw	.100						; max. value is  100 %
 	cpfslt	batt_percent				; batt_percent < 100 % ?
 	movwf	batt_percent				; NO  - limit to 100 %
-	movlw	.95						; < 95 %
-	cpfsgt	batt_percent
+	movlw	battery_cycle_counter_unlock
+	cpfsgt	batt_percent				; < threshold ?
 	bcf	lock_cycle_counter			; Yes, unlock cycle counter
 	return								; done
 
+LTC2959_get_accumulated_charge:
+	movlw	0x00						; point to status register
+	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
+	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
+	rcall	I2C_ACKEN					; send master acknowledge
+	movff	SSP1BUF,gauge_status_byte	; copy received byte to gauge_status_byte
+
+	rcall	I2C_RCEN					; enable receive mode
+	movf	SSP1BUF,W					; dump to WREG (ADC Control)
+	rcall	I2C_ACKEN					; send master acknowledge
+
+	rcall	I2C_RCEN					; enable receive mode
+	movf	SSP1BUF,W					; dump to WREG (Coulumb Counter Control)
+	rcall	I2C_ACKEN					; send master acknowledge
+
+	rcall	I2C_RCEN					; enable receive mode
+	movff	SSP1BUF,xC+3				; copy received byte to xC+3
+	rcall	I2C_ACKEN					; send master acknowledge
+
+	rcall	I2C_RCEN					; enable receive mode
+	movff	SSP1BUF,xC+2				; copy received byte to xC+2
+	rcall	I2C_ACKEN					; send master acknowledge
+	
+	rcall	I2C_RCEN					; enable receive mode
+	movff	SSP1BUF,xC+1				; copy received byte to xC+1
+	rcall	I2C_ACKEN					; send master acknowledge
+
+	rcall	I2C_RCEN					; enable receive mode
+	movff	SSP1BUF,xC+0				; copy received byte to xC+0
+	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
+
+	MOVLI	.159,xB					; 159,4745717 (0,085mAh/533nAh)
+	call	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder
+
+	; clamp to 100% here
+	tstfsz	xC+2					; Devision result > 0xFFFF
+	setf	xC+0					; Yes, make sure xC:2 is 0xFFFF
+	tstfsz	xC+2					; Devision result > 0xFFFF
+	setf	xC+1					; Yes, make sure xC:2 is 0xFFFF
+	
+	movff	xC+1,sub_a+1
+	movff	xC+0,sub_a+0				; put result in sub_a:2
+;	
+;	movff	sub_a+1,gp_debug+1
+;	movff	sub_a+0,gp_debug+0
+;	
+	bra	lt2942_get_accumulated_charge2		; continue as with LT2942
+	
+	
 lt2942_set_to_zero_percent:
+    	btfsc	battery_gauge_type			; =1: Gauge IC LTC2959, =0: LT2942
+	bra	LTC2959_set_to_zero_percent
+    
 	movlw	0x02						; point to accumulated charge registers
 	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
 	movff	battery_offset+1,SSP1BUF	; send battery offset, high byte
@@ -1254,16 +1351,40 @@
 	movff	battery_offset+0,SSP1BUF	; send battery offset, low  byte
 	rcall	WaitMSSP					; wait for TX to complete
 	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
+	bra	I2C_PEN						; stop condition (and return)
+
+LTC2959_set_to_zero_percent:
+	; multiply battery_offset:2 with 159 and write result to LTC2959
+	
+	MOVII	battery_offset,xA
+	MOVLI	.159,xB					; 159,4745717 (0,085mAh/533nAh)
+	call	mult16x16				; xC:4 = xA:2 * xB:2
+	
+	movlw	0x03						; point to accumulated charge registers
+	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
+	movff	xC+3,SSP1BUF				; send battery offset
 	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
-
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movff	xC+2,SSP1BUF				; send battery offset
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movff	xC+1,SSP1BUF				; send battery offset
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movff	xC+0,SSP1BUF				; send battery offset
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	bra	I2C_PEN						; stop condition (and return)
+    
 
 ;-----------------------------------------------------------------------------
 ; Read Gauge IC - Reset Accumulating Register to 0xFFFF
 ;
 	global	lt2942_charge_done
 lt2942_charge_done:
+        btfsc	battery_gauge_type			; =1: Gauge IC LTC2959, =0: LT2942
+	bra	lt2959_charge_done
+
 	movlw	0x02						; point to accumulated charge registers
 	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
 	setf	SSP1BUF						; data byte
@@ -1272,40 +1393,55 @@
 	setf	SSP1BUF						; data byte
 	rcall	WaitMSSP					; wait for TX to complete
 	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
+	bra	I2C_PEN						; stop condition (and return)
+
+lt2959_charge_done:
+	; Reset Accumulating Register to 0x009EFF61 (0xFFFF * .159)
+	movlw	0x03						; point to accumulated charge registers
+	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
+	movlw	0x00
+	movwf	SSP1BUF						; data byte
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movlw	0x9E
+	movwf	SSP1BUF						; data byte
 	rcall	WaitMSSP					; wait for TX to complete
-	return							; done
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movlw	0xFF
+	movwf	SSP1BUF						; data byte
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movlw	0x61
+	movwf	SSP1BUF						; data byte
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	bra	I2C_PEN						; stop condition (and return)
 
-
+	
 ;-----------------------------------------------------------------------------
 ; Helper Function - send 1 Byte to the LT2942 Gauge IC
 ;
 I2C_TX_GAUGE:
 	movwf	i2c_temp2					; save data byte to be sent
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
-	movlw	0xC8						; address byte + Write bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_SEN						; start condition
+	movlw	0xC8						; address byte + Write bit LT2942
+	btfsc	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	movlw	0xC6						; address byte + Write bit LTC2559
+	rcall	I2C_TX						; send byte
 	movf	i2c_temp2,W					; restore data byte to be sent
-	bra		I2C_TX						; send byte and return
+	bra	I2C_TX						; send byte and return
 
 
 ;-----------------------------------------------------------------------------
 ; Helper Function - receive 1 Byte from the LT2942 Gauge IC
 ;
 I2C_RX_GAUGE:
-	bsf		SSP1CON2,RSEN				; repeated start condition
-	rcall	WaitMSSP					; wait for TX to complete
-	movlw	0xC9	    					; address byte + Read bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	bra		WaitMSSP					; wait for reception and return
+	rcall	I2C_RSEN					; repeated start condition	
+	movlw	0xC9	    					; address byte + Read bit LT2942
+	btfsc	battery_gauge_type				; =1: Gauge IC LTC2959, =0: LT2942
+	movlw	0xC7						; address byte + Read bit LTC2959
+	rcall	I2C_TX						; send byte
+	bra	I2C_RCEN					; enable receive mode
 
 
 ;-----------------------------------------------------------------------------
@@ -1315,7 +1451,7 @@
 ;
 	global	reset_battery_gauge_and_lt2942
 reset_battery_gauge_and_lt2942:
-	btfsc	battery_gauge_available		; battery gauge chip available?
+	btfsc	battery_gauge_available			; battery gauge chip available?
 	call	lt2942_charge_done			; YES - reset meter to 0xFFFF
 	;bra	reset_battery_gauge			; continue resetting gauge registers
 
@@ -1357,49 +1493,34 @@
 	movlw	.5							; max number of tries for detecting a TR module
 	movwf	hy							; initialize loop counter for tries
 I2C_probe_OSTC_rx_1:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x50						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	btfss	SSP1CON2,ACKSTAT			; ACK received?
+	rcall	I2C_TX						; send byte
 	bsf		ostc_rx_present				; YES - TR module detected
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	btfss	ostc_rx_present				; was a TR module detected?
 	return								; NO  - done
 
 	WAITMS	.1							; wait 1 ms
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x50						; address byte + write bit
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 	movlw	0x1B						; command: get firmware
-	movwf	SSP1BUF						; send command
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_TX						; send byte
+	rcall	I2C_PEN						; stop condition
 
 	WAITMS	.1							; wait 1 ms
 
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x51						; address byte + Read bit
 	movwf	SSP1BUF						; control byte
 	rcall	WaitMSSP					; wait for TX to complete
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,rx_firmware_cur_major ; store as firmware version, major
-	bsf		SSP1CON2,ACKEN				  ; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 
 	; last byte in read from RX circuity always with a NACK!
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 	
@@ -1428,44 +1549,31 @@
 ;
 	global	I2C_get_tankdata
 I2C_get_tankdata:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x50						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 	movlw	0x1E						; read buffer2 (48 bytes)
-	movwf	SSP1BUF						; data byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_TX						; send byte
+	rcall	I2C_PEN						; stop condition
 
 	WAITMS	.1							; wait 1 ms
 
 	; read 48 bytes
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x51						; address byte + read bit
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 	movlw	.47							; 47 with ACK + 1 w/o ACK
 	movwf	i2c_temp2					; initialize loop counter
 	lfsr	FSR2,rx_buffer				; point to start of rx data buffer 
 I2C_get_tankdata_loop_read:
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,POSTINC2			; copy received byte to the rx buffer
 	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 	decfsz	i2c_temp2,F					; decrement loop counter, done?
 	bra		I2C_get_tankdata_loop_read	; NO  - loop
 	; read last byte without ACK
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,POSTINC2			; copy received byte to the rx buffer
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 	return							; done
@@ -1485,46 +1593,35 @@
 	movlw	.64							; initialize loop counter: 64 byte with ACK
 	movwf	i2c_temp2					; ...
 	; address write
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x50						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 	; write 64 bytes
 I2C_update_OSTC_loop:
 	TBLRD*+								; read a byte from program memory
 	movff	TABLAT,POSTINC2				; copy to send buffer
-	movff	TABLAT,SSP1BUF				; copy to I2C data buffer
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movf	TABLAT,W				; copy to W
+	rcall	I2C_TX						; send byte
 	decfsz	i2c_temp2,F					;decrement loop counter, became zero?
 	bra		I2C_update_OSTC_loop		; NO  - loop
-	bsf		SSP1CON2,PEN				; YES - stop condition
-	rcall	WaitMSSP					;     - wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	WAITMS	.1							;     - wait another 1 ms
 	; setup for read-back
 	lfsr	FSR2,buffer					; reset pointer to begin of send buffer
 	movlw	.63							; initialize loop counter: 63 byte with ACK + 1 w/o ACK
 	movwf	i2c_temp2					; ...
 	; address read-back
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x51						; address byte + read bit
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 	; read-back 64 bytes
 I2C_update_OSTC_loop_read:
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_RCEN					; enable receive mode
 	movf	SSP1BUF,W					; copy received byte to WREG
 	cpfseq	POSTINC2					; compare read-back byte with sent byte, equal?
 	bsf		i2c_error_flag				; NO  - not equal, set error flag
 	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_ACKEN					; send master acknowledge
 	decfsz	i2c_temp2,F					; decrement loop counter, became zero?
 	bra		I2C_update_OSTC_loop_read	; NO  - loop
 	; 1 w/o ACK
@@ -1536,18 +1633,12 @@
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 	WAITMS	.1
 	; address commit
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0x50						; address byte + write bit
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 	movlw	0x1F						; write command
-	movwf	SSP1BUF						; data byte
-	rcall	WaitMSSP					; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_TX						; send byte
+	rcall	I2C_PEN						; stop condition
 	WAITMS	.5							; required waiting time
 	; error check
 	btfss	i2c_error_flag				; did an error occur?
@@ -1564,70 +1655,49 @@
  	global	I2C_probe_pressure_sensor	; Do not call from ISR!
 I2C_probe_pressure_sensor:						; Probe the type of sensor, set/clear press_sensor_type
 	bcf	press_sensor_type				; MS5541 as default
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	movwf	SSP1BUF						; control byte
 	rcall	WaitMSSP					; wait for TX to complete
+	; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
 	btfss	SSP1CON2,ACKSTAT				; ACK received?
 	bsf	press_sensor_type				; MS5837 sensor found
-	bsf	SSP1CON2,PEN					; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
-	return
+	bra	I2C_PEN						; stop condition
  
 ;--------------------------------------------------------------------
 ; Helper Function - get the calibration parameter from # WREG address
 ; Do not call from ISR!
 I2C_get_calib_parameter:
 	movwf	lo						; store address
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movf	lo,W						; Point to calibration register
 	rcall	I2C_TX						; send byte
-	bsf	SSP1CON2,PEN					; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	
-	bsf	SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP				; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0xED					; address byte + read bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF					; control byte
-	rcall	WaitMSSP				; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
-	bsf	SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP				; wait for reception and return
+	rcall	I2C_TX						; send byte 
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,dMSB				; High byte
-	bsf	SSP1CON2,ACKEN					; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
-	
-	bsf	SSP1CON2,RCEN					; enable receive mode
-	rcall	WaitMSSP					; wait for reception
+	rcall	I2C_ACKEN					; send master acknowledge
+
+	rcall	I2C_OneByteRX_NACK			; receive last byte with not acknowledge
 	movff	SSP1BUF,dLSB				; Low byte
-;	bsf	SSP1CON2,ACKDT					; set ACKDT flag
-	bsf	SSP1CON2,ACKEN					; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
-;	bcf	SSP1CON2,ACKDT					; reset ACKDT flag
-	bsf	SSP1CON2,PEN					; stop condition
-	bra	WaitMSSP					; wait for TX to complete (And return)
+	bra	I2C_PEN						; stop condition
     
 	
 	global	I2C_get_calib_MS5837 ; Do not call from ISR!
 I2C_get_calib_MS5837:	
 	banksel	common
 	; first, send a reset
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x1E
 	rcall	I2C_TX						; send byte
-	bsf	SSP1CON2,PEN					; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	WAITMS	.5						; 2.8ms according to datasheet
 	
 	movlw	0xA2						; Point to C1
@@ -1664,98 +1734,86 @@
 
 	global	I2C_get_press_val_MS5837
 I2C_get_press_val_MS5837:
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+    	btfsc	i2c_reinit_sensor2				; Sensor ok?
+	rcall	I2CReset					; Try a I2C reset first
+	btfsc	i2c_reinit_sensor2				; Sensor ok?
+	bra	I2C_get_press_val_MS5837_skip			; We did a reset, restart conversion first
+	
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x00						; command byte (0x00, read ADC)
 	rcall	I2C_TX						; send byte
 	
-	bsf	SSP1CON2,RSEN				; repeated start condition
-	rcall	WaitMSSP				; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0xED					; address byte + read bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF					; control byte
-	rcall	WaitMSSP				; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 
 	bsf	i2c_busy_pressure				; reading new pressure
-	bsf	SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP				; wait for reception and return
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,D1_buffer+2					; Upper byte
-	bsf	SSP1CON2,ACKEN					; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf	SSP1CON2,RCEN					; enable receive mode
-	rcall	WaitMSSP					; wait for reception
+	rcall	I2C_ACKEN					; send master acknowledge
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,D1_buffer+1					; high byte
-	bsf	SSP1CON2,ACKEN					; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf	SSP1CON2,RCEN					; enable receive mode
-	rcall	WaitMSSP					; wait for reception
+	rcall	I2C_ACKEN					; send master acknowledge
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,D1_buffer+0					; Low byte
 
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 	bcf	i2c_busy_pressure				; reading new pressure done.
-	
+
+I2C_get_press_val_MS5837_skip:	
 	; Start temperature measurement
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
 	rcall	I2C_TX						; send byte
 	movlw	0x58						; OSR=4096, type=D2
 	rcall	I2C_TX						; send byte
-	bsf	SSP1CON2,PEN					; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	bcf	ms5837_state					; =0: result of temperature will be in the ADC
+	bcf	i2c_reinit_sensor2				; Clear error flag
     	return
 	
 	global	I2C_get_temp_val_MS5837	
 I2C_get_temp_val_MS5837:
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	btfsc	i2c_reinit_sensor2				; Sensor ok?
+	rcall	I2CReset					; Try a I2C reset first
+	btfsc	i2c_reinit_sensor2				; Sensor ok?
+	bra	I2C_get_temp_val_MS5837_skip			; We did a reset, restart conversion first
+	
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
-	movff	WREG,i2c_error_vault+0				; Store address
 	rcall	I2C_TX						; send byte
 	movlw	0x00						; command byte (0x00, read ADC)
 	rcall	I2C_TX						; send byte
 	
-	bsf	SSP1CON2,RSEN				; repeated start condition
-	rcall	WaitMSSP				; wait for TX to complete
+	rcall	I2C_RSEN					; repeated start condition	
 	movlw	0xED					; address byte + read bit
-	movff	WREG,i2c_error_vault+0				; Store address
-	movwf	SSP1BUF					; control byte
-	rcall	WaitMSSP				; wait for TX to complete
-	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	rcall	I2C_TX						; send byte
 
 	bsf	i2c_busy_temperature				; reading new temperature
-	bsf	SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP				; wait for reception and return
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,D2_buffer+2					; Upper byte
-	bsf	SSP1CON2,ACKEN					; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf	SSP1CON2,RCEN					; enable receive mode
-	rcall	WaitMSSP					; wait for reception
+	rcall	I2C_ACKEN					; send master acknowledge
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,D2_buffer+1					; high byte
-	bsf	SSP1CON2,ACKEN					; master acknowledge
-	rcall	WaitMSSP					; wait for TX to complete
-	bsf	SSP1CON2,RCEN					; enable receive mode
-	rcall	WaitMSSP					; wait for reception
+	rcall	I2C_ACKEN					; send master acknowledge
+	rcall	I2C_RCEN					; enable receive mode
 	movff	SSP1BUF,D2_buffer+0					; Low byte
 
 	rcall	I2C_MasterNotAckStop				; Master NOT acknowledge and Stop
 	bcf	i2c_busy_temperature				; reading new temperature done.
-	
+
+I2C_get_temp_val_MS5837_skip:	
 	; Start pressure measurement
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
 	rcall	I2C_TX						; send byte
 	movlw	0x48						; OSR=4096, type=D1
 	rcall	I2C_TX						; send byte
-	bsf	SSP1CON2,PEN					; stop condition
-	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_PEN						; stop condition
 	bsf	ms5837_state					; =0: result of pressure will be in the ADC
+	bcf	i2c_reinit_sensor2				; Clear error flag
 	return
 	
 	
@@ -1767,6 +1825,7 @@
 check_i2c_error:
 	btfss	i2c_error_flag
 	return
+	bcf	i2c_error_flag_lock				; arm error vault again
 	incf	message_counter,F				; increase message counter
 	goto	TFT_message_i2c_error				; show message for battery low (battery percent) and return
 
--- a/src/i2c.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/i2c.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -12,16 +12,15 @@
 	extern	I2C_init_compass
 	extern	I2C_sleep_compass
 
-	extern	lt2942_init						; init gauge IC
-	extern	lt2942_sleep					; sleep gauge IC
+	extern	battery_gauge_init						; init gauge IC
 	extern	lt2942_get_status				; read gauge IC status
 	extern	lt2942_get_voltage				; read battery voltage registers
 	extern	lt2942_get_temperature			; read battery temperature
-	extern	lt2942_get_accumulated_charge	; read battery gauge register
 	extern	lt2942_charge_done				; set  battery gauge register to fully charged
 
 	extern	reset_battery_gauge_and_lt2942	; reset battery registers and battery gauge chip
 	extern	reset_battery_gauge				; reset battery registers only
+	
 
  IFDEF _rx_functions
 	extern	I2C_probe_OSTC_rx				; set ostc_rx_present bit if present
--- a/src/isr.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/isr.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -20,7 +20,7 @@
 ;=============================================================================
 ; Code to be placed at a fixed Position
 ;
-isr_high	CODE	0x0008				; high priority interrupts
+isr_high	CODE	0x00008				; high priority interrupts
 	bra		HighInt						; jump to ISR
 
 isr_low		CODE	0x00018				; low priority interrupts *** not used ***
@@ -47,7 +47,7 @@
 	btfsc	INTCON3,INT1IF				; left button activity?
 	rcall	isr_switch_left				; YES - check left switch
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	; serve IR/S8 link timer
 	btfsc	PIR3,RC2IF					; UART 2 interrupt?
 	rcall	isr_uart2					; YES - get a byte from the IR/S8 link
@@ -56,7 +56,7 @@
  ELSE
 	bcf		PIR3,RC2IF					; clear UART 2  interrupt
 	bcf		PIR2,TMR3IF					; clear timer 3 interrupt
-	; fill-up to keep code size identical to _external_sensor variant, see "Attention" below
+	; fill-up to keep code size identical to _external_sensor_eccr variant, see "Attention" below
 	nop
 	nop
  ENDIF
@@ -113,7 +113,7 @@
 
 	; Attention: fill-up the gap between the end of this section
 	;            and the next section which starts at 0x00080 !!
-	nop
+;	nop
 	
 block_0_code_end:						; marker to find end of code in block 0 in linker report file
 
@@ -144,7 +144,7 @@
 ;
 ; take a byte received on IR/S8 link and slot it into the RX buffer
 ;
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 isr_uart2:
 	bcf		PIR3,RC2IF					; clear UART 2 interrupt flag
@@ -152,8 +152,9 @@
 	movff	RCREG2,isr_lo				; copy received byte to isr_lo
 	bcf		RCSTA2,CREN					; clear receiver status
 	bsf		RCSTA2,CREN					; ...
+;	movff	RCREG2,TXREG2 ;mH
 	banksel	isr_backup					; back to default ISR bank
-	movlw	.18							; size of the buffer
+	movlw	.64							; size of the buffer
 	cpfslt	ir_s8_counter				; number of received bytes < buffer size?
 	bra		isr_uart2_1					; NO  - buffer full, do not store the byte
 	movf	ir_s8_counter,W				; YES - copy number of received bytes to WREG
@@ -183,32 +184,94 @@
 	movlw	.16							; a IR telegram may also have 16 bytes, with last byte 0x00
 	cpfseq	ir_s8_counter				; got exactly 16 bytes?
 	bra		isr_timer3_2				; NO  - test for 17 bytes
+	banksel	common2					; ir_s8_buffer is in common2
 	tstfsz	ir_s8_buffer+.15			; YES - last byte = 0x00 ?
 	bra		isr_timer3_exit				;       NO  - exit
 	bra		isr_timer3_ir				;       YES - got 16 bytes, compute local checksum
 isr_timer3_2:
 	movlw	.17							; a S8 telegram has 17 bytes
 	cpfseq	ir_s8_counter				; got exactly 17 bytes?
-	bra		isr_timer3_exit				; NO  - exit
+	bra		isr_timer3_3				; NO  - test for 57 bytes
 	bra		isr_timer3_s8				; YES - S8 data
+isr_timer3_3:
+	movlw	.57							; an eccr telegram has 57 bytes
+	cpfseq	ir_s8_counter				; got exactly 17 bytes?
+	bra		isr_timer3_exit				; NO  - exit
+	bra		isr_timer3_eccr				; YES - eccr data
 
+isr_timer3_eccr:	
+ ;	; process telegram received on S8 link
+	banksel	isr_backup					; default bank for all ISR code is bank ISR data
+	movlw	.55							; compute checksum over 1st and next 55 bytes
+	rcall	compute_IR_S8_checksum		; compute checksum
+
+
+;	tstfsz	ir_s8_counter				; checksum ok?
+;	bra		isr_timer3_exit				; NO - discard data
+	
+	; copy received data to respective variables
+;	movff	ir_s8_buffer+.1,hud_status_byte
+	movff	ir_s8_buffer+.9,s8_rawdata_sensor1+0
+	movff	ir_s8_buffer+.10,s8_rawdata_sensor1+1
+	movff	ir_s8_buffer+.11,s8_rawdata_sensor1+2
+	movff	ir_s8_buffer+.12,sensor1_ppO2
+	movff	ir_s8_buffer+.13,s8_rawdata_sensor2+0
+	movff	ir_s8_buffer+.14,s8_rawdata_sensor2+1
+	movff	ir_s8_buffer+.15,s8_rawdata_sensor2+2
+	movff	ir_s8_buffer+.16,sensor2_ppO2
+	movff	ir_s8_buffer+.17,s8_rawdata_sensor3+0
+	movff	ir_s8_buffer+.18,s8_rawdata_sensor3+1
+	movff	ir_s8_buffer+.19,s8_rawdata_sensor3+2
+	movff	ir_s8_buffer+.20,sensor3_ppO2
+	movff	ir_s8_buffer+.27,hud_battery_mv+0
+	movff	ir_s8_buffer+.28,hud_battery_mv+1	    ; External battery voltage in mV
+	movff	ir_s8_buffer+.29,ccr_status_byte+0
+	movff	ir_s8_buffer+.30,ccr_status_byte+1
+
+	clrf	hud_status_byte
+	
+	; manually build HUD status byte for ccr testing
+	btfsc	ccr_status_byte+0,0
+	bsf	sensor1_active
+	btfsc	ccr_status_byte+0,0
+	bsf	sensor1_calibrated_ok
+	
+	
+	
+	btfsc	ccr_status_byte+0,1
+	bsf	sensor2_active
+	btfsc	ccr_status_byte+0,1
+	bsf	sensor2_calibrated_ok
+	
+	btfsc	ccr_status_byte+0,2
+	bsf	sensor3_active
+	btfsc	ccr_status_byte+0,2
+	bsf	sensor3_calibrated_ok
+	
+	bsf		trigger_S8_data_update		; YES - set flag for new data available
+	;bsf	ext_input_optical
+	bsf	ext_s8_full_digital			; Set flag for external S8 full digital mode
+	bsf		hud_connection_ok			; set manually for eccr
+	bra		isr_timer3_reload			; reload timer and exit
+	
 	; process telegram received on IR link
 isr_timer3_ir:
+	banksel	isr_backup					; default bank for all ISR code is bank ISR data
 	movlw	.12							; compute checksum over 1st and next 12 bytes
 	rcall	compute_IR_S8_checksum		; compute checksum
 	tstfsz	ir_s8_counter				; checksum ok?
 	bra		isr_timer3_exit				; NO - discard data
 
 	; copy received data to respective variables
-	movff	ir_s8_buffer+.1, hud_status_byte
-	movff	ir_s8_buffer+.2, sensor1_mv+0
-	movff	ir_s8_buffer+.3, sensor1_mv+1
-	movff	ir_s8_buffer+.4, sensor2_mv+0
-	movff	ir_s8_buffer+.5, sensor2_mv+1
-	movff	ir_s8_buffer+.6, sensor3_mv+0
-	movff	ir_s8_buffer+.7, sensor3_mv+1
-	movff	ir_s8_buffer+.8, sensor1_ppO2
-	movff	ir_s8_buffer+.9, sensor2_ppO2
+	movff	ir_s8_buffer+.1,hud_status_byte
+	movff	ir_s8_buffer+.2,sensor1_mv+0
+	movff	ir_s8_buffer+.3,sensor1_mv+1
+	movff	ir_s8_buffer+.4,sensor2_mv+0
+	movff	ir_s8_buffer+.5,sensor2_mv+1
+	movff	ir_s8_buffer+.6,sensor3_mv+0
+	movff	ir_s8_buffer+.7,sensor3_mv+1
+	movff	ir_s8_buffer+.8,sensor1_ppO2
+	movff	ir_s8_buffer+.9,sensor2_ppO2
 	movff	ir_s8_buffer+.10,sensor3_ppO2
 	movff	ir_s8_buffer+.11,hud_battery_mv+0
 	movff	ir_s8_buffer+.12,hud_battery_mv+1
@@ -233,12 +296,12 @@
 	bsf		trigger_S8_data_update		; YES - set flag for new data available
 
 	; copy more received data to respective variables
-	movff	ir_s8_buffer+.4, s8_rawdata_sensor1+0
-	movff	ir_s8_buffer+.5, s8_rawdata_sensor1+1
-	movff	ir_s8_buffer+.6, s8_rawdata_sensor1+2
-	movff	ir_s8_buffer+.7, s8_rawdata_sensor2+0
-	movff	ir_s8_buffer+.8, s8_rawdata_sensor2+1
-	movff	ir_s8_buffer+.9, s8_rawdata_sensor2+2
+	movff	ir_s8_buffer+.4,s8_rawdata_sensor1+0
+	movff	ir_s8_buffer+.5,s8_rawdata_sensor1+1
+	movff	ir_s8_buffer+.6,s8_rawdata_sensor1+2
+	movff	ir_s8_buffer+.7,s8_rawdata_sensor2+0
+	movff	ir_s8_buffer+.8,s8_rawdata_sensor2+1
+	movff	ir_s8_buffer+.9,s8_rawdata_sensor2+2
 	movff	ir_s8_buffer+.10,s8_rawdata_sensor3+0
 	movff	ir_s8_buffer+.11,s8_rawdata_sensor3+1
 	movff	ir_s8_buffer+.12,s8_rawdata_sensor3+2
@@ -247,6 +310,7 @@
 	movlw	ir_timeout_value			; get timeout value (in multiples of 62.5 ms)
 	movwf	ir_s8_timeout				; reload timeout counter
 isr_timer3_exit:
+	banksel	isr_backup					; default bank for all ISR code is bank ISR data
 	clrf	ir_s8_counter				; clear number of received bytes
 	bcf		PIR2,TMR3IF					; clear IRQ flag
 	return								; done
@@ -260,24 +324,24 @@
 	MOVII	FSR0L,FSR0_backup			; back-up FSR0
 	lfsr	FSR0,ir_s8_buffer			; load base address of the receive buffer
 	movff	POSTINC0,isr_mpr+0			; initialize low byte of the calculated checksum with first byte in buffer
-	clrf	         isr_mpr+1			; clear the high byte of the calculated checksum
+	clrf	isr_mpr+1				; clear the high byte of the calculated checksum
 compute_IR_S8_checksum_loop:
-	movf	POSTINC0,W					; read next byte
-	addwf	isr_mpr+0,F					; add it to the to checksum, low  byte
-	movlw	.0							; no explicit data to add to the high byte...
-	addwfc	isr_mpr+1,F					; ... besides the carry
+	movf	POSTINC0,W				; read next byte
+	addwf	isr_mpr+0,F				; add it to the to checksum, low  byte
+	movlw	.0					; no explicit data to add to the high byte...
+	addwfc	isr_mpr+1,F				; ... besides the carry
 	decfsz	ir_s8_counter,F				; decrement number of bytes yet to do, all done?
-	bra		compute_IR_S8_checksum_loop	; NO  - loop
-	movf	POSTINC0,W					; YES - read     low  byte of the received   checksum
-	cpfseq	isr_mpr+0					;     - equal to low  byte of the calculated checksum?
+	bra	compute_IR_S8_checksum_loop		; NO  - loop
+	movf	POSTINC0,W				; YES - read     low  byte of the received   checksum
+	cpfseq	isr_mpr+0				;     - equal to low  byte of the calculated checksum?
 	incf	ir_s8_counter,F				;       NO - mark a checksum error
-	movf	POSTINC0,W					;     - read     high byte of the received   checksum
-	cpfseq	isr_mpr+1					;     - equal to high byte of the calculated checksum?
+	movf	POSTINC0,W				;     - read     high byte of the received   checksum
+	cpfseq	isr_mpr+1				;     - equal to high byte of the calculated checksum?
 	incf	ir_s8_counter,F				;       NO - mark a checksum error
 	MOVII	FSR0_backup,FSR0L			;     - restore FSR0
-	return								;     - done
+	return						;     - done
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
  
 ;-----------------------------------------------------------------------------
@@ -362,7 +426,7 @@
 	cpfseq	CCPR1L						; = current PWM value?
 	rcall	isr_dimm_tft				; NO - adjust until max_CCPR1L = CCPR1L
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 	decfsz	ir_s8_timeout,F				; decrement IR/S8 timeout counter, became zero?
 	bra		isr_sensor_state2			; NO  - continue with sensor
@@ -370,6 +434,8 @@
 	movwf	ir_s8_timeout				;     - reload timeout timer
 	btfsc	ext_input_optical			;     - optical input in use?
 	bra		isr_tmr7_5					;       YES - clear data
+	btfsc	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	bra		isr_tmr7_5					;       YES - clear data
 	TSTOSS	opt_s8_mode					;       NO  - S8 input in use?
 	bra		isr_sensor_state2			;             NO  - must be analog interface in use, keep data
 	;bra	isr_tmr7_5					;             YES - clear data
@@ -396,7 +462,7 @@
 
 	bsf		trigger_S8_data_update		; signal a data update
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 isr_sensor_state2:
 	btfss	speed_is_normal						; CPU running on normal speed?
@@ -435,18 +501,22 @@
 	call	calculate_compensation				; calculate temperature compensated pressure (27 us)
 
 	; build average for pressure
-	;bcf		STATUS,C							; clear carry bit - not needed since we don't use the +2 register later
+	bcf		STATUS,C					; clear carry bit
 	rrcf	pressure_abs_avg+2					; divide by 2
 	rrcf	pressure_abs_avg+1					; ...
 	rrcf	pressure_abs_avg+0					; ...
-	;bcf		STATUS,C							; clear carry bit - not needed since we don't use the +2 register later
+	bcf		STATUS,C					; clear carry bit
 	rrcf	pressure_abs_avg+2					; divide by 2, again
 	rrcf	pressure_abs_avg+1					; ...
 	rrcf	pressure_abs_avg+0					; ...
 
 	; export averaged pressure
+	tstfsz	pressure_abs_avg+2					; must be zero for all depths < 262m
+	bra	isr_sensor_state_sensor_error				; assume a false reading if <> 0
+	
 	MOVII	pressure_abs_avg,pressure_abs		; export result (Which is 16 bit for all depths < 262m)
 
+isr_sensor_state_sensor_resume:
 	; build average for temperature
 	bcf		STATUS,C							; clear carry bit by default
 	btfsc	temperature_avg+1,7					; sign bit set?
@@ -458,8 +528,13 @@
 	bsf		STATUS,C							; YES - copy sign bit to carry bit
 	rrcf	temperature_avg+1					; divide signed temperature by 2 again (by 4 in total now)
 	rrcf	temperature_avg+0					; ...
+	
+	btfsc	i2c_reinit_sensor2					; Sensor ok?
+	bra	isr_sensor_state_skip_temp				; likely not, skip updating the temperature
+	
 	MOVII	temperature_avg,temperature_cur		; store final result
 
+isr_sensor_state_skip_temp:
 	; check for temperature change
 	movf	temperature_cur+0,W					; get current temperature, low  byte
 	cpfseq	temperature_last+0					; compare with last temperature, equal?
@@ -569,7 +644,10 @@
 	bsf		PIE5,TMR7IE					; re-enable IRQs by TMR7
 	bra		isr_adjust_speed			; set/restore CPU speed and return
 
-
+isr_sensor_state_sensor_error:
+	bsf	i2c_reinit_sensor2				; Do an I2C reset and reinitialize the pressure sensor type 2 
+								; Done in I2C_get_press_val_MS5837 and I2C_get_temp_val_MS5837
+	bra	isr_sensor_state_sensor_resume			; Ignore the reading and continue
 ;-----------------------------------------------------------------------------
 ; Helper Function for Display Dimming
 ;
--- a/src/menu_processor.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/menu_processor.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -98,7 +98,7 @@
 	; draw menu title
 	WIN_BOX_BLACK   dm_menu_row+.2,dm_menu_row+.26,dm_menu_left+.2,dm_menu_right-.2	; clear menu title area
 	WIN_SMALL .2, dm_menu_row+.2							; set menu title font and position
-	FONT_COLOR color_greenish				; set menu title font color
+	FONT_COLOR color_green				; set menu title font color
 	movff	menu_title_addr+0,FSR1L			; point to multi-lingual menu title text
 	movff	menu_title_addr+1,FSR1H			; ...
 	call	strcpy_text_FSR					; copy translated text into the buffer
@@ -128,7 +128,7 @@
 	; draw menu title
 	WIN_BOX_BLACK   .2,.23,.0,.159			; clear menu title area
 	WIN_STD .0, .2							; set menu title font and position
-	FONT_COLOR color_greenish				; set menu title font color
+	FONT_COLOR color_green				; set menu title font color
 	movff	menu_title_addr+0,FSR1L			; point to multi-lingual menu title text
 	movff	menu_title_addr+1,FSR1H			; ...
 	call	strcpy_text_FSR					; copy translated text into the buffer
@@ -145,7 +145,7 @@
 	PRINT									; output menu title
 
 	; draw footer line
-	FONT_COLOR_MEMO							; select default color
+	FONT_COLOR color_green				; set menu title font color
 	WIN_TINY   .5, .224						; tiny font, left position
 	STRCPY_TEXT_PRINT tNext					; print "Next"
 	WIN_TINY .124, .224						; tiny font, righ position
@@ -268,6 +268,7 @@
 	global	menu_vertical
 menu_vertical:
 	rcall	menu_draw_menu_items			; draw all menu items
+	bcf	force_all_caps				; clear flag (which is only used in dn hardware)
 	movlw	CCP1CON_VALUE					; load PWM setting
 	btfss	divemode						; in dive mode?
 	movwf	CCP1CON							; NO - power-on backlight
--- a/src/menu_tree.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/menu_tree.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -164,7 +164,7 @@
 do_menu_ccr:
 	call	option_cleanup_oCCRMode		; in pSCR mode, revert AutoSP (2) to calculated SP (0)
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 	bcf		imprint_sensor_mv			; stop imprinting of live O2 sensor mV data
 	btfss	ext_input_s8_ana			; S8/analog sensor input available?
@@ -181,7 +181,7 @@
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 do_menu_ccr_2:
 	MENU_BEGIN	tCCRSetup, .5			; OSTC 2 menu
@@ -197,7 +197,7 @@
 ; CCR / pSCR Setup - 2nd Level
 ;
 do_menu_ccr_more:
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	MENU_BEGIN	tCCRSetup, .7			; CCR/pSCR more menu
 		MENU_OPT_INC	tS8Mode,					oS8Mode
 		MENU_OPT_INC	tCCmaxFracO2,				oCCmaxFracO2
@@ -216,12 +216,12 @@
 		MENU_OPT_INC	tPSCR_lungratio,			oPSCR_lungratio
 		MENU_CALL		tBack,						do_return_menu_ccr
 	MENU_END
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
  ENDIF	; _ccr_pscr
 
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Calibration Menu
@@ -250,7 +250,7 @@
 	movff	WREG,customview_surfmode	; show this custom view when back in surface mode
 	bra		do_restart					; exit menu
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 
  IFDEF _ccr_pscr
@@ -807,6 +807,8 @@
 ; Dive Settings Menu - 1st Layer
 ;
 do_menu_dive:
+	btfsc	dn_flag	; force menu all caps in dn hardware
+	bsf	force_all_caps
 	MENU_BEGIN	tDiveModeMenu, .6
 		MENU_CALL		tDiveSetup,					do_menu_dive_dive		; dive setup
 		MENU_CALL		tDecoSetup,					do_menu_dive_deco		; deco setup
@@ -956,6 +958,8 @@
 		MENU_OPT_INC	tIBCDwarning,				oEnable_IBCD				; IBCD warning
 		MENU_CALL		tBack,						do_return_menu_dive
  ELSE
+	btfsc	dn_flag	; force menu all caps in dn hardware
+	bsf	force_all_caps
 	MENU_BEGIN	tppO2Setup, .4
 		MENU_DYNAMIC	dyn_ppo2_max,				do_toggle_ppO2_max_work		; max work
 		MENU_DYNAMIC	dyn_ppo2_max_deco,			do_toggle_ppO2_max_deco		; max deco
@@ -1138,6 +1142,9 @@
 ; Settings Menu - 1st Layer
 ;
 do_menu_settings:
+	btfsc	dual_comm				    ; Dual comm hardware (USB and BLE-only)?
+	bra	do_menu_settings_dual_comm		    ; Use this menu here on the first layer
+    
  IFDEF _hwos_sport
 	bsf		ble_available				; required for very old OSTC sport
  ENDIF
@@ -1179,6 +1186,17 @@
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
+do_menu_settings_dual_comm:
+	MENU_BEGIN	tSystSets, .7
+		MENU_CALL		tInfoMenu,					do_menu_info
+		MENU_CALL		tBleTitle,					do_comm_mode_bt
+		MENU_CALL		tUsbTitle,					do_comm_mode_usb
+		MENU_CALL		tSetTimeDate,					do_menu_date_time
+		MENU_CALL		tDispSets,					do_menu_dispsets
+		MENU_CALL		tSysSets,					do_menu_syssets
+		MENU_CALL		tBack,						do_return_main_menu
+	MENU_END
+    
 
 ;-----------------------------------------------------------------------------
 ; Call Functions - start Communication Mode (BT and USB)
@@ -1294,10 +1312,11 @@
 ;
 do_menu_info2:
  IFNDEF _comm_debug
-	MENU_BEGIN	tInfoMenu, .6
+	MENU_BEGIN	tInfoMenu, .7
 		MENU_DYNAMIC	dyn_show_battery_volts,		0
 		MENU_DYNAMIC	dyn_show_battery_cycles,	0
 		MENU_DYNAMIC	dyn_show_config,			0
+		MENU_DYNAMIC	dyn_show_config2,			0
 		MENU_DYNAMIC	dyn_show_sensor_calib,		0
 		MENU_DYNAMIC	dyn_show_sensor_offset,		0
 		MENU_CALL		tBack,						do_return_menu_settings_deeper
@@ -1355,12 +1374,21 @@
 	output_hex					; print as hex
 	call	get_cpu_version				; get CPU version
 	output_hex					; print as hex
-	btfss	less_io_cpu				; =1: OSTC has a CPU with less I/O pins
 	return						; Done.
-	PUTC	"*"
+
+dyn_show_config2:	
+	STRCAT_TEXT tHardware				; print  text
+	movf	HW_variants2,W				; copy hardware variants2  to WREG
+	output_hex					; print as hex
+	movf	HW_variants3,W				; copy hardware variants3  to WREG
+	output_hex					; print as hex
+	PUTC	"/"					; print a separator
+	movff	i2c_error_counter+1,WREG
+	output_hex					; print as hex
+	movff	i2c_error_counter+0,WREG
+	output_hex					; print as hex
 	return						; Less I/O CPU done.
 
-
 ;-----------------------------------------------------------------------------
 ; dynamic Title - show Pressure Sensor Calibration Data C1 and C5
 ;
@@ -1598,6 +1626,9 @@
 ; Settings Menu - 3rd Layer - Display Settings - Brightness
 ;
 do_menu_Brightness: 
+	btfss	ambient_sensor
+	bra	do_menu_Brightness2
+	
     	MENU_BEGIN	tBright, .4
 		MENU_OPT_INC	tBrightDive,					oBrightness_dive
 		MENU_OPT_INC	tBrightSurface,					oBrightness_surface
@@ -1605,6 +1636,12 @@
 		MENU_CALL	tBack,						do_return_dispsets_menu
 	MENU_END
 
+do_menu_Brightness2:	
+    	MENU_BEGIN	tBright, .3
+		MENU_OPT_INC	tBrightDive,					oBrightness_dive
+		MENU_OPT_INC	tBrightSurface,					oBrightness_surface
+		MENU_CALL	tBack,						do_return_dispsets_menu
+	MENU_END
  
 ;-----------------------------------------------------------------------------
 ; Settings Menu - 3rd Layer - Display Settings - Color Schemes
@@ -1634,6 +1671,8 @@
 		MENU_CALL		tBack,						do_return_menu_settings_deeper
 	MENU_END
  ELSE
+	btfsc	dn_flag	; force menu all caps in dn hardware
+	bsf	force_all_caps
 	MENU_BEGIN	tDispSets, .6
 		MENU_OPT_INC	tVSIgraph,					oVSIgraph
 		MENU_OPT_INC	tVSItext2,					oVSItext
@@ -1675,9 +1714,15 @@
 ; Settings Menu - 2nd Layer - System Settings
 ;
 do_menu_syssets:
+	btfsc	dn_flag				; dn hardware?
+	bra	do_menu_syssets_dn		; YES
+	btfsc	dual_comm			; Dual comm hardware?
+	bra	do_menu_syssets_dual_comm	; YES
 	btfsc	battery_gauge_available		; piezo buttons available?
-	bra		do_menu_syssets_piezo		; YES
+	bra	do_menu_syssets_piezo		; YES
 
+do_menu_syssets_dual_comm:	
+do_menu_syssets_mechanical:
  IFDEF _compass
 	MENU_BEGIN	tSystSets, .4													; All MENU_CALLs in this menu
 		MENU_CALL		tCompassMenu,				do_menu_compass				; need to stay together on this
@@ -1693,6 +1738,26 @@
 	MENU_END
  ENDIF	; _compass
 
+	
+do_menu_syssets_dn:
+ IFDEF _compass
+	MENU_BEGIN	tSystSets, .5													; All MENU_CALLs in this menu
+		MENU_CALL		tCompassMenu,				do_menu_compass				; need to stay together on this
+		MENU_CALL		tLogOffset,					do_menu_log_offset			; menu level in order to not
+		MENU_CALL		tResetMenu,					do_menu_reset				; mess up the menu stack on doing
+		MENU_OPT_INC		tBLE_Compatibility,				oBLE_Compatibility			; BLE Compatibility mode
+		MENU_CALL		tBack,						do_return_menu_settings		; the do_return_menu_settings !
+	MENU_END
+ ELSE
+	MENU_BEGIN	tSystSets, .4													; see above
+		MENU_CALL		tLogOffset,					do_menu_log_offset			;
+		MENU_CALL		tResetMenu,					do_menu_reset				;
+		MENU_OPT_INC		tBLE_Compatibility,				oBLE_Compatibility			; BLE Compatibility mode
+		MENU_CALL		tBack,						do_return_menu_settings		;
+	MENU_END
+ ENDIF	; _compass
+ 
+ 
 do_menu_syssets_piezo:
  IFDEF _compass
 	MENU_BEGIN	tSystSets, .5
@@ -1897,6 +1962,8 @@
 ; Settings Menu - 3rd Layer - System Settings - Reset Menus
 ;
 do_menu_reset:
+       	btfsc	dn_flag
+	bra	do_menu_reset_dn
 	MENU_BEGIN	tResetMenu, .7
 		MENU_CALL		tBack,						do_return_menu_syssets_more
 		MENU_CALL		tReboot,					do_menu_reset_reboot	; confirm
@@ -1904,7 +1971,17 @@
 		MENU_CALL		tResetSettings,				do_menu_reset_settings	; confirm
 		MENU_CALL		tResetLogbook,				do_menu_reset_logbook	; confirm
 		MENU_CALL		tResetBattery,				do_menu_reset_battery	; confirm
-		MENU_CALL		tResetBLE2,				do_menu_reset_ble2	; Configure the new BLE module
+		MENU_CALL		tResetBLE2,				do_menu_reset_ble2	; (Re-) Configure the new BLE module
+	MENU_END
+
+do_menu_reset_dn:	; no reset battery for dn
+	MENU_BEGIN	tResetMenu, .6
+		MENU_CALL		tBack,						do_return_menu_syssets_more
+		MENU_CALL		tReboot,					do_menu_reset_reboot	; confirm
+		MENU_CALL		tResetDeco,					do_menu_reset_deco		; confirm
+		MENU_CALL		tResetSettings,				do_menu_reset_settings	; confirm
+		MENU_CALL		tResetLogbook,				do_menu_reset_logbook	; confirm
+		MENU_CALL		tResetBLE2,				do_menu_reset_ble2	; (Re-) Configure the new BLE module
 	MENU_END
 
 
@@ -2155,6 +2232,9 @@
 	btfsc	dn_flag
 	bra	use_404050_battery
 	
+	btfsc	dual_comm
+	bra	use_404050_battery
+	
 	movlw	0x11						; OSTC 2 (2015 model)
 	cpfseq	HW_descriptor
 	bra		$+4
@@ -2338,7 +2418,7 @@
 ; Helper Function - finish Battery Selection
 ;
 use_batt_exit:
-	call	reset_battery_gauge_and_lt2942	; reset battery hard- and software gauge
+	call	reset_battery_gauge_and_lt2942			; reset battery hard- and software gauge
 
 use_batt_exit_1:
  IFNDEF _screendump
@@ -2403,9 +2483,9 @@
 setup_new_panasonic:
 	bcf		charge_disable				; release  charging-inhibit signal
 	bsf		charge_enable				; tristate charging-inhibit signal
-	MOVLI	capacity_panasonic_internal, battery_capacity_internal
-	MOVLI	capacity_panasonic,          battery_capacity
-	MOVLI	offset_panasonic,            battery_offset
+	MOVLI	capacity_14500_internal, battery_capacity_internal
+	MOVLI	capacity_14500,          battery_capacity
+	MOVLI	offset_14500,            battery_offset
 	movlw	.2
 	movwf	battery_type
 	return
@@ -2440,6 +2520,7 @@
 setup_new_404050:
 	bcf		charge_disable				; release  charging-inhibit signal
 	bsf		charge_enable				; tristate charging-inhibit signal
+	
 	CLRI	battery_capacity_internal
 	MOVLI	capacity_404050, battery_capacity
 	MOVLI	offset_404050,   battery_offset
--- a/src/ms5541.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/ms5541.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -635,93 +635,93 @@
 	movlw	d'13'						; send command
 	rcall	send_data_MS5541			; ...
 	rcall	get_2bytes_MS5541			; read result
-	movff	dMSB,ir_s8_buffer+1			; copy result, high byte first
-	movff	dLSB,ir_s8_buffer+0			; copy result, low  byte second
+	movff	dMSB,ms5541_rawdata+1			; copy result, high byte first
+	movff	dLSB,ms5541_rawdata+0			; copy result, low  byte second
 
 	movlw	b'01011000'					; +3*high as start and 1+low as stop
 	movwf	dbuffer						; ...
 	movlw	d'13'						; send command
 	rcall	send_data_MS5541			; ...
 	rcall	get_2bytes_MS5541			; read result
-	movff	dMSB,ir_s8_buffer+3			; copy result, high byte first
-	movff	dLSB,ir_s8_buffer+2			; copy result, low  byte second
+	movff	dMSB,ms5541_rawdata+3			; copy result, high byte first
+	movff	dLSB,ms5541_rawdata+2			; copy result, low  byte second
 
 	movlw	b'01100100'					; +3*high as start and 1+low as stop
 	movwf	dbuffer						; ...
 	movlw	d'13'						; send command
 	rcall	send_data_MS5541			; ...
 	rcall	get_2bytes_MS5541			; read result
-	movff	dMSB,ir_s8_buffer+5			; copy result, high byte first
-	movff	dLSB,ir_s8_buffer+4			; copy result, low  byte second
+	movff	dMSB,ms5541_rawdata+5			; copy result, high byte first
+	movff	dLSB,ms5541_rawdata+4			; copy result, low  byte second
 
 	movlw	b'01101000'					; +3*high as start and 1+low as stop
 	movwf	dbuffer						; ...
 	movlw	d'13'						; send command
 	rcall	send_data_MS5541			; ...
 	rcall	get_2bytes_MS5541			; read result
-	movff	dMSB,ir_s8_buffer+7			; copy result, high byte first
-	movff	dLSB,ir_s8_buffer+6			; copy result, low  byte second
+	movff	dMSB,ms5541_rawdata+7			; copy result, high byte first
+	movff	dLSB,ms5541_rawdata+6			; copy result, low  byte second
 
 	; calculate C1 (16 Bit)
-	movff	ir_s8_buffer+1,C1+1
+	movff	ms5541_rawdata+1,C1+1
 	bcf		STATUS,C
 	rrcf	C1+1
 	bcf		STATUS,C
 	rrcf	C1+1
 	bcf		STATUS,C
 	rrcf	C1+1
-	movff	ir_s8_buffer+0,C1+0
+	movff	ms5541_rawdata+0,C1+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+1,0
+	btfss	ms5541_rawdata+1,0
 	bcf		STATUS,C
 	rrcf	C1+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+1,1
+	btfss	ms5541_rawdata+1,1
 	bcf		STATUS,C
 	rrcf	C1+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+1,2
+	btfss	ms5541_rawdata+1,2
 	bcf		STATUS,C
 	rrcf	C1+0
 
 	; calculate C2 (16 Bit)
-	movff	ir_s8_buffer+2, C2+0
+	movff	ms5541_rawdata+2, C2+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+3,0
+	btfss	ms5541_rawdata+3,0
 	bcf		STATUS,C
 	rrcf	C2+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+3,1
+	btfss	ms5541_rawdata+3,1
 	bcf		STATUS,C
 	rrcf	C2+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+3,2
+	btfss	ms5541_rawdata+3,2
 	bcf		STATUS,C
 	rrcf	C2+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+3,3
+	btfss	ms5541_rawdata+3,3
 	bcf		STATUS,C
 	rrcf	C2+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+3,4
+	btfss	ms5541_rawdata+3,4
 	bcf		STATUS,C
 	rrcf	C2+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+3,5
+	btfss	ms5541_rawdata+3,5
 	bcf		STATUS,C
 	rrcf	C2+0
 
-	movff	ir_s8_buffer+3, C2+1
+	movff	ms5541_rawdata+3, C2+1
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+0,0
+	btfss	ms5541_rawdata+0,0
 	bcf		STATUS,C
 	rrcf	C2+1
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+0,1
+	btfss	ms5541_rawdata+0,1
 	bcf		STATUS,C
 	rrcf	C2+1
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+0,2
+	btfss	ms5541_rawdata+0,2
 	bcf		STATUS,C
 	rrcf	C2+1
 	bcf		STATUS,C
@@ -732,29 +732,29 @@
 	rrcf	C2+1
 
 	; calculate C3 (16 Bit)
-	movff	ir_s8_buffer+5,C3+0
+	movff	ms5541_rawdata+5,C3+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+4,7
+	btfss	ms5541_rawdata+4,7
 	bcf		STATUS,C
 	rlcf	C3+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+4,6
+	btfss	ms5541_rawdata+4,6
 	bcf		STATUS,C
 	rlcf	C3+0
 	clrf	C3+1
-	btfsc	ir_s8_buffer+5,7
+	btfsc	ms5541_rawdata+5,7
 	bsf		C3+1,1
-	btfsc	ir_s8_buffer+5,6
+	btfsc	ms5541_rawdata+5,6
 	bsf		C3+1,0
 
 	; calculate C4 (16 Bit)
-	movff	ir_s8_buffer+7,C4+0
+	movff	ms5541_rawdata+7,C4+0
 	bsf		STATUS,C
-	btfss	ir_s8_buffer+6,7
+	btfss	ms5541_rawdata+6,7
 	bcf		STATUS,C
 	rlcf	C4+0
 	clrf	C4+1
-	btfsc	ir_s8_buffer+7,7
+	btfsc	ms5541_rawdata+7,7
 	bsf		C4+1,0
 
 	; C4=C4-250
@@ -766,21 +766,21 @@
 	movwf	C4+1
 
 	; calculate C5 (16 Bit)
-	movff	ir_s8_buffer+4,C5+0
+	movff	ms5541_rawdata+4,C5+0
 	bcf		C5+0,6
-	btfsc	ir_s8_buffer+2,0
+	btfsc	ms5541_rawdata+2,0
 	bsf		C5+0,6
 	bcf		C5+0,7
-	btfsc	ir_s8_buffer+2,1
+	btfsc	ms5541_rawdata+2,1
 	bsf		C5+0,7
 	clrf	C5+1
-	btfsc	ir_s8_buffer+2,2
+	btfsc	ms5541_rawdata+2,2
 	bsf		C5+1,0
-	btfsc	ir_s8_buffer+2,3
+	btfsc	ms5541_rawdata+2,3
 	bsf		C5+1,1
-	btfsc	ir_s8_buffer+2,4
+	btfsc	ms5541_rawdata+2,4
 	bsf		C5+1,2
-	btfsc	ir_s8_buffer+2,5
+	btfsc	ms5541_rawdata+2,5
 	bsf		C5+1,3
 
 	; calculate C5 = UT1
@@ -798,7 +798,7 @@
 
 	; calculate C6 (16Bit)
 	clrf	C6+1
-	movff	ir_s8_buffer+6,C6+0
+	movff	ms5541_rawdata+6,C6+0
 	bcf		C6+0,7
 
 get_calibration_data2:
--- a/src/option_table.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/option_table.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -309,7 +309,7 @@
 	OPTION_ENUM8    oTr2ndPres,      tr_pres_options,                              .0,      tTrPresNone,     0x0F2,    0x80,  opt_TR_2nd_pres				; TR functions - 2nd pressure assignment
 	OPTION_ENUM8    oTrBailPres,     tr_pres_options,                              .1,      tTrPresNone,     0x0F3,    0x81,  opt_TR_Bail_pres				; TR functions - bailout pressure assignment
 	OPTION_UINT8p5  oTrMaxDeltaPres, max_pres_diff_min, max_pres_diff_max,         .5,      tbar,            0x0F4,    0x82,  char_I_max_pres_diff			; TR functions - maximum delta pressure in independent double mode
-	;                                                                                                        0x0F5											; not used
+	OPTION_BOOL     oBLE_Compatibility,					       .0,                       0x0F5,    0x83,  opt_BLE_compatibility			; =1: configure BLE name to hwOS style for dn hardware
 	;                                                                                                        0x0F6											; not used
 	OPTION_ENUM8    o2ndDepthDisp,       .2,                                       .0,      tMax,            0x0F7,    0x85,  opt_2ndDepthDisp				; =1: show average depth instead of max depth
 	OPTION_UINT8p3d oMaxDepth,          .30,            ostc_depth_max,    ostc_depth_max,  tMeters,         0x0F8,    0x86,  opt_max_depth					; depth at which a warning will be given
@@ -358,7 +358,7 @@
 	OPTION_UINT8    oSetHours,           .0,                  .23,                 .0,      nounit,       volatile,  nocomm,  rtc_latched_hour				; ...
 	OPTION_UINT8    oSetDay,             .1,                  .31,                 .0,      nounit,       volatile,  nocomm,  rtc_latched_day				; ...
 	OPTION_UINT8    oSetMonth,           .1,                  .12,                 .0,      nounit,       volatile,  nocomm,  rtc_latched_month				; ...
-	OPTION_UINT8    oSetYear,           .18,                  .24,                 .0,      nounit,       volatile,  nocomm,  rtc_latched_year				; ...
+	OPTION_UINT8    oSetYear,    firmware_creation_year, firmware_expire_year+.5,  .0,      nounit,       volatile,  nocomm,  rtc_latched_year				; ...
 
 	OPTION_UINT8    oFallback,           .0,                 .255,                 .0,      nounit,       volatile,    0x38,  opt_fallback					; unused dummy option for compatibility with 3rd party tools
 	OPTION_UINT8    oConservatism,       .0,                 .255,                 .0,      nounit,       volatile,    0x47,  opt_conservatism				; unused dummy option for compatibility with 3rd party tools
--- a/src/options.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/options.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -596,12 +596,14 @@
 	movlw	0x1F							; serial ID of option oCCRMode
 	cpfseq	opt_serial						; editing oCCRMode right now?
 	bra		option_inc_enum8_2				; NO  - check next option
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	ext_input_s8_ana				; YES - S8/analog input available?
 	bra		option_inc_enum8_1a				;       YES - setting 'sensor' allowed
 	btfsc	ext_input_optical				;     - optical interface available?
 	bra		option_inc_enum8_1a				;       YES - setting 'sensor' allowed
- ENDIF	; _external_sensor
+	btfsc	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	bra		option_inc_enum8_1a				;       YES - setting 'sensor' allowed
+ ENDIF	; _external_sensor_eccr
 	movf	INDF1,W							;       NO to both - get mode (=0: fixed SP, =1: Sensor, =2: AutoSP)
 	xorlw	.1								;                  - in sensor mode?
 	bnz		option_inc_enum8_1a				;                    NO  - continue with next check
@@ -980,12 +982,14 @@
 	banksel	common							;     - back to bank common
 	bsf		option_changed					;     - flag that EEPROM needs to be updated
 option_cleanup_oCCRMode_CCR:				; continue from above & jump-in from start.asm if known to be in CCR mode
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	ext_input_s8_ana				; S8/analog interface available?
 	return									; YES - setting 'sensor' allowed
 	btfsc	ext_input_optical				; does hosting OSTC have an optical interface?
 	return									; YES - setting 'sensor' allowed
- ENDIF	; _external_sensor
+	btfsc	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	return									; YES - setting 'sensor' allowed
+ ENDIF	; _external_sensor_eccr
 	movff	opt_ccr_mode,WREG				; NO to both - get CCR mode
 	xorlw	.1								;            - coding for sensor
 	tstfsz	WREG							;            - CCR mode = sensor?
--- a/src/p2_deco.c	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/p2_deco.c	Thu Nov 27 18:32:58 2025 +0100
@@ -1482,9 +1482,13 @@
 	if( char_depth_sim > internal_deco_depth[stop_index] )
 	    char_depth_sim = internal_deco_depth[stop_index];
 
-	// if using straight Buhlmann: done, stop needed
-	if( char_I_model == 0 ) return(1);
-
+    // using straight Buhlmann?
+    if( char_I_model == 0 )
+    {
+        // yes, reached surface?
+        if( char_depth_sim == 0 ) return(0);  // yes, no stop when at the surface
+        else                      return(1);  // no,  stop needed
+    } 
 	// -----------------------------------------------------------------------
 	// we need to make or hold a stop and we are using the GF extension
 	// -----------------------------------------------------------------------
@@ -2048,6 +2052,84 @@
 	char_I_sim_advance_time = 0;
 }
 
+//////////////////////////////////////////////////////////////////////////////
+// calc_GF_surface
+//
+// Calculates the instantaneous surface GF (GF_surf) for the leading compartment.
+//
+// Definition:
+//   GF_surf = (P_tissue - pres_surface) / (M_surf - pres_surface)
+//
+// - P_tissue  : current inert gas tissue pressure (N2 + He) in bar
+// - pres_surface : pres_surface (Ambient pressure at the surface, in bar)
+// - M_surf    : M-value on the surface (per calc_M_value_at_pressure)
+//
+// The maximum across all compartments is taken as GF_surf.
+// The result is written in percent (0..250) in int_O_GF_surface.
+//
+static float calc_M_value_at_pressure(float pres_surface)
+{
+    float a, b;
+    read_Buhlmann_coefficients();
+#ifdef _helium
+    adopt_Buhlmann_coefficients();
+    a = var_a;
+    b = var_b;
+#else    
+    a = var_N2_a;
+    b = var_N2_b;
+#endif
+    return a + b * pres_surface;
+}
+
+static void calc_GF_surface(void)
+{
+    overlay float P_tissue;
+    overlay float M_surf;
+    overlay float gf_surf;
+    overlay float gf_surf_max = 0.0f;
+
+    // Pass through all compartments
+    for (ci = 0; ci < NUM_COMP; ci++)
+    {
+#ifdef _helium
+        P_tissue = real_pres_tissue_N2[ci] + real_pres_tissue_He[ci];
+#else
+        P_tissue = real_pres_tissue_N2[ci];
+#endif
+
+        // M-value on the surface for this compartment
+        M_surf = calc_M_value_at_pressure(pres_surface);
+
+        // Filtering out unnecessary cases
+        if (M_surf <= pres_surface)
+            continue;
+
+        // Surface-GF of this compartment
+        gf_surf = (P_tissue - pres_surface) / (M_surf - pres_surface);
+
+        // Keep biggest result in gf_surf
+        if (gf_surf > gf_surf_max)
+            gf_surf_max = gf_surf;
+    }
+
+    // Convert to %
+    if (gf_surf_max <= 0.0f)
+    {
+        int_O_GF_surface = 0;
+    }
+    else
+    {
+        unsigned int tmp;
+
+        tmp = (unsigned int)(gf_surf_max * 100.0f + 0.5f);
+
+        if (tmp > 999)
+            tmp = 999;
+
+        int_O_GF_surface = tmp;
+    }
+}
 
 //////////////////////////////////////////////////////////////////////////////
 // Reset all tissues to surface pressure equilibrium state
@@ -2307,6 +2389,9 @@
 
 		// convert the CNS value to integer
 		convert_cur_CNS_for_display();
+        
+        // compute the surface GF
+        calc_GF_surface();
 
 	} // tasks every 2 seconds
 
--- a/src/ports.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/ports.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -80,7 +80,7 @@
 
 ; PORTJ
 #DEFINE	RJ0_unused		PORTJ,0			; unused
-#DEFINE	RJ1_unused		PORTJ,1			; unused
+#DEFINE	vibration_en		PORTJ,1			; Vibration motor enable (OSTC X hardware)
 #DEFINE	CHRG_OUT		PORTJ,2			; CHRG_OUT
 #DEFINE	CHRG_IN 		PORTJ,3			; CHRG_IN
 #DEFINE	vusb_in			PORTJ,4			; external power supply detect, USB enumerated
--- a/src/shared_definitions.h	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/shared_definitions.h	Thu Nov 27 18:32:58 2025 +0100
@@ -232,6 +232,7 @@
 
 VAR_UCHAR (char_I_dil_check);					// =1: check ppO2 of the pure diluent against current setpoint
 
+VAR_UINT  (int_O_GF_surface);					// instantaneous surface GF (GF_surf) for the leading compartment
 
 #ifdef __18CXX
 	//---- BANK 4 DATA -------------------------------------------------------
--- a/src/simulator.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/simulator.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -441,7 +441,7 @@
 ;         decoplan_page = page number.
 ;
 deco_results_page:
-	FONT_COLOR color_greenish
+	FONT_COLOR color_green
  IFDEF _ccr_pscr
 	btfss	bailout_mode					; bailout results?
 	bra		deco_results_page_1				; NO
@@ -790,7 +790,7 @@
 	cpfseq	gas_index						; all gases shown?
 	bra		deco_results_gas_loop			; NO - loop
 
-	FONT_COLOR color_greenish				; set color
+	FONT_COLOR color_green				; set color
 	TEXT_SMALL .80,.01,tGasUsage			; "Gas Usage"
 
 	btfsc	decoplan_show_pressures			; showing pressures in bar?
--- a/src/sleepmode.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/sleepmode.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -201,44 +201,6 @@
     	bcf		switch_right				; clear right button event
 	bcf		switch_left				; clear left  button event
 
-	btfsc	battery_gauge_available			; is a battery gauge IC available?
-	bra		one_sec_sleep_1					; YES - check for charger
-	btfsc	ble_available				; Skip "USB" check in all Bluetooth models (Required for very old OSTC sport)
-	bra		one_sec_sleep_2					;     - continue
-	btfsc	vusb_in							; NO  - USB plugged in?
-	bcf		sleepmode						;       YES - terminate sleep mode
-	bra		one_sec_sleep_2					;     - continue
-
-one_sec_sleep_1:
-	call	get_battery_voltage				; check for charger
-
-	; Test if charging
-	btfss	cc_active						; charging?
-	bra		one_sec_sleep_1a				; NO
-	btfsc	charge_in_sleep					; YES - already showing charge screen?
-	bra		one_sec_sleep_1b				;       YES - only update data
-
-	bsf		charge_in_sleep
-	bcf		deep_sleep						; wake-up from deepsleep
-	call	TFT_boot						; initialize TFT (includes clear screen)
-	movlw	.32
-	movff	WREG,max_CCPR1L					; bank safe
-	call	TFT_Display_FadeIn				; dim up the display
-one_sec_sleep_1b:
-	call	TFT_surfmode_batt				; show battery type, voltage and color-coded percentage
-	bra		one_sec_sleep_2					; continue
-
-one_sec_sleep_1a:
-	btfss	charge_in_sleep					; was showing charge screen?
-	bra		one_sec_sleep_2					; NO
-
-	; yes, power-down screen    
-	call	TFT_Display_FadeOut				; power-down backlight
-	call	TFT_DisplayOff					; power-down display
-	bcf		charge_in_sleep
-
-
-one_sec_sleep_2:
 	incf	sm_timer_10sec,F				; increment 10 seconds timer
 	movlw	.10								; load  a 10 into WREG
 	cpfslt	sm_timer_10sec					; timer < 10 yet?
@@ -250,14 +212,7 @@
 	btfsc	trigger_full_hour				; one hour in sleep?
 	rcall	one_hour_sleep					; YES - do the every hour tasks
 
-	; sleepmode pressure sampling for new sensor is done here
-	btfss	press_sensor_type				; New sensor found?
-	return							; No, done.
-
-	btfsc	ms5837_state					; =0: result of temperature is in the ADC
-	goto	I2C_get_press_val_MS5837			; (Will clear ms5837_state) (And return!)
-	goto	I2C_get_temp_val_MS5837				; (Will set ms5837_state) (And return!)
-	; done.
+	return	; done.
 
 
 	
@@ -267,6 +222,46 @@
 ten_sec_sleep:
 	; tasks every 10 seconds in sleep mode
 	clrf	sm_timer_10sec					; clear timer
+
+	btfsc	battery_gauge_available			; is a battery gauge IC available?
+	bra		ten_sec_sleep_1					; YES - check for charger
+	btfsc	ble_available				; Skip "USB" check in all Bluetooth models (Required for very old OSTC sport)
+	bra		ten_sec_sleep_2					;     - continue
+	btfsc	vusb_in							; NO  - USB plugged in?
+	bcf		sleepmode						;       YES - terminate sleep mode
+	bra		ten_sec_sleep_2					;     - continue
+
+ten_sec_sleep_1:
+	call	get_battery_voltage				; check for charger
+
+	; Test if charging
+	btfss	cc_active						; charging?
+	bra		ten_sec_sleep_1a				; NO
+	btfsc	charge_in_sleep					; YES - already showing charge screen?
+	bra		ten_sec_sleep_1b				;       YES - only update data
+
+	bsf		charge_in_sleep
+	bcf		deep_sleep						; wake-up from deepsleep
+	call	TFT_boot						; initialize TFT (includes clear screen)
+	movlw	.32
+	movff	WREG,max_CCPR1L					; bank safe
+	call	TFT_Display_FadeIn				; dim up the display
+ten_sec_sleep_1b:
+	call	TFT_surfmode_batt				; show battery type, voltage and color-coded percentage
+	bra		ten_sec_sleep_2					; continue
+
+ten_sec_sleep_1a:
+	btfss	charge_in_sleep					; was showing charge screen?
+	bra		ten_sec_sleep_2					; NO
+
+	; yes, power-down screen    
+	call	TFT_Display_FadeOut				; power-down backlight
+	call	TFT_DisplayOff					; power-down display
+	bcf		charge_in_sleep
+
+
+ten_sec_sleep_2:
+
 	rcall	pressuretest_sleep_fast			; get pressure without averaging (faster)
 	MOVLI	wake_up_from_sleep,sub_a		; load wake-up pressure (1160 mbar) into sub_a
 	MOVII	pressure_abs,      sub_b		; load current absolute pressure    into sub_b
@@ -403,6 +398,8 @@
 ;
 deepsleep_get_accel:
 	call	I2C_init_compass				; start compass
+	btfss	compass_present
+	bcf	deep_sleep				; No Compass - terminate deep sleep mode
 	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 	call	I2C_RX_accelerometer			; read accelerometer
 	call	I2C_RX_accelerometer			; read accelerometer
@@ -417,6 +414,21 @@
 ; faster method to save some power in sleep mode
 ;
 pressuretest_sleep_fast:
+    	; sleepmode pressure sampling for new sensor is done here
+	btfss	press_sensor_type				; New sensor found?
+	bra	pressuretest_sleep_fast2			; No
+
+	btfsc	ms5837_state					; =0: result of temperature is in the ADC
+	bra	pressuretest_sleep_fast1			; was =1 -> Read pressure from MS5837. ms5837_state will always be zero here from now on
+	call	I2C_get_temp_val_MS5837				; (Will set ms5837_state)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
+pressuretest_sleep_fast1:	
+	call	I2C_get_press_val_MS5837			; (Will clear ms5837_state)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
+
+pressuretest_sleep_fast2:
 	banksel	isr_backup						; select bank ISR data
 
 	clrf	pressure_abs_avg+0				; clear pressure    average register
--- a/src/start.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/start.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -144,6 +144,7 @@
 	bsf		screen_type2					; set flags for later clear of the false one
 	bsf		screen_type3					; ...
 	bsf		screen_type4					; ...
+	bsf		screen_type5					; ...
 	movlw	0x80							; set up read from 0x01F780
 	movwf	TBLPTRL							; ...
 	;movlw	0xF7							; high and upper are still at 0x01F7xx
@@ -160,10 +161,15 @@
 	movlw	0x85							; coding for screen type 4
 	cpfseq	TABLAT							; equal?
 	bcf		screen_type4					; NO  -  not screen type 4
+	movlw	0x86							; coding for screen type 5
+	cpfseq	TABLAT							; equal?
+	bcf		screen_type5					; NO  -  not screen type 5
 
 	bcf	dn_flag
 	btfsc	screen_type4
 	bsf	dn_flag
+	btfsc	screen_type5
+	bsf	dn_flag
 	
 	; get button polarity from configuration data (EEPROM)
 	EEPROM_CC_READ eeprom_button_polarity,button_polarity
@@ -365,13 +371,15 @@
 	bcf		tft_power						; inverted, here needed for I2C_probe_OSTC_rx, to wake-up RX circuity
 	bsf		ambient_sensor					; set ambient light sensor as available by default
 	bsf		ext_input_optical				; set optical input        as available by default
+	bcf		ext_s8_full_digital				; clear flag
 
 	call	lt2942_get_status				; check for gauge IC
 	btfss	battery_gauge_available			; OSTC 2, cR or TR?
 	bra		restart2						; NO
 
 	; OSTC 2, cR or TR
-	call	lt2942_init						; initialize battery gauge IC
+	call	battery_gauge_init						; initialize battery gauge IC
+	call	lt2942_get_voltage
 	bcf		ext_input_optical				; OSTC 2, cR and TR do not have an optical input
 
 	banksel	ANCON0							; ANCON0 is outside access RAM
@@ -388,7 +396,35 @@
 	bsf		lightsen_power					; power-up ambient light sensor again
 
 restart2:
-    	btfsc	less_io_cpu						; Less I/O CPU found?
+	; Dual comm hardware (USB and BLE-only)?
+	bsf	dual_comm						; assume dual comm hardware by default
+	movlw	0xFC							; set up read from 0x01FFFC
+	movwf	TBLPTRL							; ...
+	movlw	0xFF							; ...
+	movwf	TBLPTRH							; ...
+	movlw	0x01							; ...
+	movwf	TBLPTRU							; ...
+	TBLRD*+								; read configuration byte
+	movlw	0x6E							; coding for dual comm 
+	cpfseq	TABLAT							; equal?
+	bcf	dual_comm						; NO
+	TBLRD*+								; read configuration byte
+	movlw	0x61							; coding for dual comm 
+	cpfseq	TABLAT							; equal?
+	bcf	dual_comm						; NO
+	TBLRD*+								; read configuration byte
+	movlw	0x6E							; coding for dual comm 
+	cpfseq	TABLAT							; equal?
+	bcf	dual_comm						; NO
+	TBLRD*+								; read configuration byte
+	movlw	0x6F							; coding for dual comm 
+	cpfseq	TABLAT							; equal?
+	bcf	dual_comm						; NO
+    
+	btfsc	dual_comm
+	bcf	ambient_sensor						; dual-comm has no ambient sensor
+	
+	btfsc	less_io_cpu						; Less I/O CPU found?
 	bsf	ble_available						; Yes, must have BLE (old or new)
  IFNDEF _hwos_sport
 	btfsc	vusb_in							; USB power detected?
@@ -402,7 +438,7 @@
 
 restart3:
     bsf		ble_npower						; power down BT chip (if available)
-   IFDEF _external_sensor						; Compiled for external analog interface?
+   IFDEF _external_sensor_eccr						; Compiled for external analog interface?
     bsf	    ext_input_s8_ana					;       YES - Set the flag
     call    eeprom_serial_number_read	; read OSTC serial number
     movlw   .31
@@ -584,7 +620,7 @@
 restart_set_modes_and_flags:
 	call	disable_ir_s8_analog			; switch off IR/S8/analog interface by default (for all compile versions!)
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	WAITMS	d'100'							; wait 100 ms to S8-HUD powered down properly
  ENDIF
 
@@ -639,9 +675,9 @@
  IFDEF _rx_functions
 	call	option_cleanup_oTrMode_CCR		;     - revert TR mode from 'ind.double' to 'on'
  ENDIF	; _rx_functions
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	call	enable_ir_s8_analog				;     - enable IR/S8/analog interface
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
  ENDIF	; _ccr_pscr
 	return									;     - done
 
@@ -673,9 +709,9 @@
  IFDEF _rx_functions
 	call	option_cleanup_oTrMode_no_CCR	;     - revert TR mode from 'CCR Dil+O2' to 'on'
  ENDIF	; _rx_functions
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	call	enable_ir_s8_analog				;     - enable IR/S8/analog interface
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
  ENDIF	; _ccr_pscr
 	return									;     - done
 
--- a/src/surfmode.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/surfmode.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -28,7 +28,7 @@
 #include "rx_ops.inc"
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 #include "calibrate.inc"
  ENDIF
 
@@ -79,10 +79,15 @@
 	bra		surfloop_1					; YES
 
 	; show heinrichs weikamp gmbh logo
-	WIN_TOP  .40
+	movlw	.40
+	btfsc	dn_flag
+	movlw	.100
+	movwf	win_top
 	WIN_LEFT .10
 	TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block
 
+	btfsc	dn_flag
+	bra	surfloop_0
 	; set font color
 	FONT_COLOR color_white
 
@@ -96,6 +101,7 @@
 	WIN_SMALL .35,.180
 	PUTC	"v"							; print "v"
 	call	TFT_print_firmware			; print full firmware version (may change the font color)
+surfloop_0:	
 	call	TFT_Display_FadeIn			; dim up the display
 
 surfloop_1:
@@ -115,7 +121,7 @@
 	movff	WREG,char_I_const_ppO2		; store it as current setpoint
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	call	transmit_setpoint			; transmit current setpoint (in cbar) via S8 digital interface (currently disabled)
  ENDIF
 
@@ -131,7 +137,7 @@
 	call	deco_calc_desaturation_time	; calculate desaturation and no-fly/no-altitude time (C-code)
 	banksel	common						; back to bank common
 
-	WAITS	.2							; wait 2 seconds
+	WAITS	.1							; wait 1 second
 
 	;---- fade to standard surface view --------------------------------------
 
@@ -144,7 +150,7 @@
 
 	;---- button functionalities ---------------------------------------------
 
-	FONT_COLOR			color_lightblue					; set font color
+	FONT_COLOR		color_green				; set font color
 	WIN_SMALL			menu_pos_column,menu_pos_row	; set font size and output position
 	STRCPY_TEXT_PRINT	tMenu							; print "<Menu"
 	WIN_SMALL			view_column,view_row			; set font size and output position
@@ -152,7 +158,8 @@
 
 
 	;---- logo in upper right corner -----------------------------------------
-
+	btfsc	dn_flag
+	bra	surfloop_3
 	; show textual OSTC logo
 	WIN_STD .100,.2						; set output position
 	FONT_COLOR color_white				; set text color to white
@@ -167,7 +174,13 @@
  ELSE
 	STRCPY_PRINT "tech"					; show "tech"
  ENDIF
-
+	bra	surfloop_4
+surfloop_3:
+	WIN_TINY .105,.5						; set output position
+	FONT_COLOR color_grey				; set text color to white
+	STRCPY_PRINT "DYNAMICNORD"					; show "OSTC"
+	
+surfloop_4:	
 	; firmware version
 	WIN_TINY .100,.32					; set output position
 	FONT_COLOR color_white				; set text color to white
@@ -491,10 +504,10 @@
 housekeeping_1ab:
 	call	I2C_get_press_val_MS5837		; (Will clear ms5837_state)
 housekeeping_1aa:	
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	imprint_sensor_mv			;     - shall imprint sensor mV data?
 	call	TFT_imprint_menu_mV			;       YES - imprint sensor mV data
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 	btfss	imprint_surfmode_data		;     - shall imprint all surface mode data?
 	bra		housekeeping_2				;       NO
 
@@ -504,7 +517,7 @@
 	btfsc	STATUS,Z					;           - equal?
 	call	TFT_surface_compass_heading	;             YES - update compass view
  ENDIF	; _compass
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	btfsc	FLAG_ccr_mode				;           - in CCR mode?
 	bra		housekeeping_1a				;           - YES - handle sensors
 	btfsc	FLAG_pscr_mode				;           - in pSCR mode?
@@ -522,7 +535,7 @@
 	xorlw	.9							;     - coding of sensor mV readings custom view
 	btfsc	STATUS,Z					;     - equal?
 	call	TFT_imprint_surf_mV			;       YES - update mV readings
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 housekeeping_2:
 	btfss	trigger_full_minute			; new 1/1 minute begun?
--- a/src/text_english.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/text_english.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -30,7 +30,7 @@
 	TCODE	tLastDecostopSurf,	"Last Deco :"			; last deco stop depth Surface Custom View
 	TCODE	tDvSalinitySurf,	"Salinity  :"			; Salinity
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tSensorMilliVolt,	"Sensors mV"			; Sensors mV
  ENDIF
 
@@ -49,7 +49,7 @@
 	TCODE	tDivemenu_Setpoint,	"Setpoint"				; Setpoint
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDivemenu_UseSensor,"use Sensor"			; Use Sensor
  ENDIF
 
@@ -103,7 +103,7 @@
 	TCODE	tTrMaxDeltaP,		"max deltaP: "			; independent double max diffenerce
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 ;	TCODE	tCCRSensor,			"Sensor"				; CCR/pSCR Sensor
 	TCODE	tCalibrateMenu,		"Calibration"			; Calibration
 	TCODE	tCalibrationGas,	"Cal. Gas O2:"			; Cal. Gas O2:
@@ -453,6 +453,7 @@
 	TCODE	taGFactors,			"aGF Values"			; aGF Values
 	TCODE	tGFInfo,			"Saturation"			; Saturation
 	TCODE	tCeiling,			"Ceiling"				; Ceiling
+	TCODE	tDiveSurfGF,			"Surface GF"				; Surface GF (max. 10 chars)
 	TCODE	tDiveFallback,		"Fallback!"				; Fallback! (max. nine chars)
 	TCODE	tDecoInfo,			"Deco Zone"				; Deco info
 	TCODE	tSensorCheck,		"Sensor Check"			; Sensor Check
@@ -492,7 +493,7 @@
 	TCODE	tswap,				"Swap Tank"				; swap tank (max. 9 chars)
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDiveHudMask1,		"Sensor 1"
 	TCODE	tDiveHudMask2,		"Sensor 2"
 	TCODE	tDiveHudMask3,		"Sensor 3"
@@ -574,7 +575,7 @@
 	TCODE	tBackingUp,			"backing up..."			; backing up current firmware
 	TCODE	tRestoring,			"restoring..."			; restoring  backup  firmware
  ENDIF
-
+	TCODE	tBLE_Compatibility,		"Legacy BLE:"
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Set   Hours"			; Set   Hours
--- a/src/text_french.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/text_french.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -30,7 +30,7 @@
 	TCODE	tLastDecostopSurf,	"Dern.Palier:"			; last deco stop depth Surface Custom View
 	TCODE	tDvSalinitySurf,	"Salinité   :"			; Salinity
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tSensorMilliVolt,	"Cellules mV"			; Sensors mV
  ENDIF
 
@@ -49,7 +49,7 @@
 	TCODE	tDivemenu_Setpoint,	"Setpoint"				; Setpoint
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDivemenu_UseSensor,"Cellules"				; Use Sensor
  ENDIF
 
@@ -103,7 +103,7 @@
 	TCODE	tTrMaxDeltaP,		"max deltaP: "			; independent double max diffenerce
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 ;	TCODE	tCCRSensor,			"Cellules CCR"			; CCR Sensor
 	TCODE	tCalibrateMenu,		"Calibration"			; Calibration
 	TCODE	tCalibrationGas,	"Cal. Gaz O2:"			; Cal. Gas O2:
@@ -454,6 +454,7 @@
 	TCODE	taGFactors,			"Valeurs aGF"			; aGF Values
 	TCODE	tGFInfo,			"Saturation"			; Saturation
 	TCODE	tCeiling,			"Plafond"				; Ceiling
+	TCODE	tDiveSurfGF,			"GF Surface"				; Surface GF (max. 10 chars)
 	TCODE	tDiveFallback,		"Fallback!"				; Fallback! (max. nine chars)
 	TCODE	tDecoInfo,			"Zone Déco"				; Deco info
 	TCODE	tSensorCheck,		"  Ctrl Cell."			; Sensor Check
@@ -493,7 +494,7 @@
 	TCODE	tswap,				"Bloc Ech."				; swap tank (max. 9 chars)
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDiveHudMask1,		"Cell. 1"
 	TCODE	tDiveHudMask2,		"Cell. 2"
 	TCODE	tDiveHudMask3,		"Cell. 3"
@@ -575,6 +576,7 @@
 	TCODE	tBackingUp,			"backing up..."			; backing up current firmware
 	TCODE	tRestoring,			"restoring..."			; restoring  backup  firmware
  ENDIF
+	TCODE	tBLE_Compatibility,		"BLE hérité:"
 
 
 ; Set Time Menu/Set Date Menu
--- a/src/text_german.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/text_german.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -30,7 +30,7 @@
 	TCODE	tLastDecostopSurf,	"Letzt.Stop:"			; last deco stop surface custom view
 	TCODE	tDvSalinitySurf,	"Salinität :"			; Salinity
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tSensorMilliVolt,	"Sensoren mV"			; Sensors mV
  ENDIF
 
@@ -49,7 +49,7 @@
 	TCODE	tDivemenu_Setpoint,	"Setpoint"				; Setpoint
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDivemenu_UseSensor,"akt.Sensor"			; Use Sensor
  ENDIF
 
@@ -103,7 +103,7 @@
 	TCODE	tTrMaxDeltaP,		"max Diff.: "			; independent double max difference
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 ;	TCODE	tCCRSensor,			"Sensor"				; CCR/pSCR Sensor
 	TCODE	tCalibrateMenu,		"Kalibrierung"			; Calibration
 	TCODE	tCalibrationGas,	"Kal. Gas O2:"			; Cal. Gas O2:
@@ -454,6 +454,7 @@
 	TCODE	taGFactors,			"aGF Werte"				; aGF Values
 	TCODE	tGFInfo,			"Sättigung"				; Saturation
 	TCODE	tCeiling,			"Ceiling"				; Ceiling
+	TCODE	tDiveSurfGF,			"Oberfl. GF"				; Surface GF (max. 10 chars)
 	TCODE	tDiveFallback,		"Fallback!"				; Fallback! (max. nine chars)
 	TCODE	tDecoInfo,			"Deko Zone"				; Deco info
 	TCODE	tSensorCheck,		"Sensor Test"			; Sensor Check
@@ -493,7 +494,7 @@
 	TCODE	tswap,				"wechseln"				; switch tank (max. 9 chars)
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDiveHudMask1,		"Sensor 1"
 	TCODE	tDiveHudMask2,		"Sensor 2"
 	TCODE	tDiveHudMask3,		"Sensor 3"
@@ -575,7 +576,7 @@
 	TCODE	tBackingUp,			"Sicherung läuft..."	; backing up current firmware
 	TCODE	tRestoring,			"Wiederherstellung..."	; restoring  backup  firmware
  ENDIF
-
+	TCODE	tBLE_Compatibility,		"Vorgänger BLE:"
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Stunden einst."		; Set Hours
--- a/src/text_italian.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/text_italian.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -30,7 +30,7 @@
 	TCODE	tLastDecostopSurf,	"UltimaTappa:"			; last deco stop surface custom view
 	TCODE	tDvSalinitySurf,	"Salinita':"			; Salinity
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tSensorMilliVolt,	"Sensori mV"			; Sensors mV
  ENDIF
 
@@ -49,7 +49,7 @@
 	TCODE	tDivemenu_Setpoint,	"Setpoint"				; Setpoint
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDivemenu_UseSensor,"Usa Sensori"			; Use Sensor
  ENDIF
 
@@ -103,7 +103,7 @@
 	TCODE	tTrMaxDeltaP,		"DeltaP Max: "			; independent double max diffenerce
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 ;	TCODE	tCCRSensor,			"Sensori CCR"			; CCR Sensor
 	TCODE	tCalibrateMenu,		"Calibrazione"			; Calibration
 	TCODE	tCalibrationGas,	"Cal. Gas O2:"			; Cal. Gas O2:
@@ -454,6 +454,7 @@
 	TCODE	taGFactors,			"Valori aGF"			; aGF Values
 	TCODE	tGFInfo,			"Saturazione"			; Saturation
 	TCODE	tCeiling,			"Tetto"					; Ceiling
+	TCODE	tDiveSurfGF,			"Surface GF"				; Surface GF
 	TCODE	tDiveFallback,		"Fallback!"				; Fallback! (max. nine chars)
 	TCODE	tDecoInfo,			"Zona Deco" 			; Deco info ("Curva Deco")
 	TCODE	tSensorCheck,		"Testa Sensori"			; Sensor Check
@@ -493,7 +494,7 @@
 	TCODE	tswap,				"CambioGas"				; swap tank (max. 9 chars
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	TCODE	tDiveHudMask1,		"Sensore1"
 	TCODE	tDiveHudMask2,		"Sensore2"
 	TCODE	tDiveHudMask3,		"Sensore3"
@@ -575,7 +576,7 @@
 	TCODE	tBackingUp,			"backing up..."			; backing up current firmware
 	TCODE	tRestoring,			"restoring..."			; restoring  backup  firmware
  ENDIF
-
+	TCODE	tBLE_Compatibility,		"Legacy BLE:"
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Imposta Ora"			; Set Hours
--- a/src/text_multilang.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/text_multilang.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -22,7 +22,7 @@
 ; fast hack **ONLY** for **CHANGING** languages ( en / de / fr / it )
 
 ;#undefine _language_1
-;#define   _language_1 fr
+;#define   _language_1 fr 
 
 ;#undefine _language_2
 ;#define   _language_2 it
--- a/src/tft.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/tft.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -73,6 +73,8 @@
 TFT_ClearScreen:
     	btfsc	screen_type4			; screen type 4?
 	bra		TFT_ClearScreen_display4; YES
+    	btfsc	screen_type5			; screen type 5?
+	bra		TFT_ClearScreen_display4; YES
 	btfsc	screen_type3			; screen type 3?
 	bra		TFT_ClearScreen_display3; YES
 	btfsc	screen_type2			; screen type 2?
@@ -373,6 +375,10 @@
 	btfsc	screen_type4			; display type 4 ?
 	bra		TFT_boot_screen4		; YES
 
+	btfsc	screen_type5			; display type 5 ?
+	bra		TFT_boot_screen5		; YES
+
+	
 	; Data Transfer Synchronization
 	Parameter_out 0x00, 0x00
 	Parameter_out 0x00, 0x00
@@ -547,178 +553,99 @@
 	movf	TABLAT,W
 	rcall	TFT_DataWrite			; write configuration
 	bra		display1_init_loop		; loop
-
+	
 TFT_boot_screen4:
-	movlw	0xB0
+        movlw	0x11
 	rcall	TFT_CmdWrite
-	movlw	0x00
-	rcall	TFT_DataWrite
-	movlw	0xC4
-	rcall	TFT_DataWrite
-	
-	movlw	0xB1
-	rcall	TFT_CmdWrite
-	movlw	0xC0
-	rcall	TFT_DataWrite
-	
-	movlw	0x3A
-	rcall	TFT_CmdWrite
-	movlw	0x55
-	rcall	TFT_DataWrite
-	
+	WAITMS	d'120'
+
 	movlw	0x36		    ; x/y mirror, see page 125 of ST7789V datasheet
 	rcall	TFT_CmdWrite
-	movlw	0x40		    ; 0x40 (normal orientation)
-	rcall	TFT_DataWrite
-	
-	movlw	0xB0
-	rcall	TFT_CmdWrite
-	movlw	0x00
-	rcall	TFT_DataWrite
-	
-	movlw	0xB2
-	call	TFT_CmdWrite
-	movlw	0x0C
-	rcall	TFT_DataWrite
-	movlw	0x0C
-	rcall	TFT_DataWrite
-	movlw	0x00
-	rcall	TFT_DataWrite
-	movlw	0x33
-	rcall	TFT_DataWrite
-	movlw	0x33
-	rcall	TFT_DataWrite
-	
-	movlw	0xB7
-	rcall	TFT_CmdWrite
-	movlw	0x75
-	rcall	TFT_DataWrite
-	
-	movlw	0xBB
-	rcall	TFT_CmdWrite
-	movlw	0x20
-	rcall	TFT_DataWrite
-	
-	movlw	0xC0
-	rcall	TFT_CmdWrite
-	movlw	0x2C
-	rcall	TFT_DataWrite
-	
-	movlw	0xC2
-	rcall	TFT_CmdWrite
-	movlw	0x01
-	rcall	TFT_DataWrite
-	
-	movlw	0xC3
-	rcall	TFT_CmdWrite
-	movlw	0x19
-	rcall	TFT_DataWrite
-	
-	movlw	0xC4
-	rcall	TFT_CmdWrite
-	movlw	0x20
-	rcall	TFT_DataWrite
-	
-	movlw	0xC6
-	rcall	TFT_CmdWrite
-	movlw	0x0F
+	movlw	0x80		    ; 0x80 (flipped orientation)
+	btfss	flip_screen	    ; 180° rotation?
+	movlw	0x40		    ; NO, 0x40 (normal orientation)
 	rcall	TFT_DataWrite
 	
-	movlw	0xD0
-	rcall	TFT_CmdWrite
-	movlw	0xA7
-	rcall	TFT_DataWrite
-	movlw	0xA1
-	rcall	TFT_DataWrite
-	
-	movlw	0xBB
-	rcall	TFT_CmdWrite
-	movlw	0x35
-	rcall	TFT_DataWrite
-	
-	movlw	0xC0
-	rcall	TFT_CmdWrite
-	movlw	0x2C
-	rcall	TFT_DataWrite
+	movlw	LOW   display4_config_table
+	movwf	TBLPTRL
+	movlw	HIGH  display4_config_table
+	movwf	TBLPTRH
+	movlw	UPPER display4_config_table
+	movwf	TBLPTRU	
+	bra	display45_init_loop		; use common loop
 	
-	movlw	0xC2
-	rcall	TFT_CmdWrite
-	movlw	0x01
-	rcall	TFT_DataWrite
-	
-	movlw	0xC3
+TFT_boot_screen5:
+        movlw	0x11
 	rcall	TFT_CmdWrite
-	movlw	0x11
-	rcall	TFT_DataWrite
+	WAITMS	d'120'
 
-	movlw	0xC4
+	movlw	0x36
 	rcall	TFT_CmdWrite
-	movlw	0x20
-	rcall	TFT_DataWrite
-
-	movlw	0xC6
-	rcall	TFT_CmdWrite
-	movlw	0x0F
+	movlw	b'11001000'	    ; 0xC8 (flipped orientation)
+	btfss	flip_screen	    ; 180° rotation?
+	movlw	b'00001000'	    ; NO, 0x08 (normal orientation)
 	rcall	TFT_DataWrite
 	
-	movlw	0xD0
-	rcall	TFT_CmdWrite
-	movlw	0xA7
-	rcall	TFT_DataWrite
-	movlw	0xA1
-	rcall	TFT_DataWrite
-	
-	movlw	0xBB
-	rcall	TFT_CmdWrite
-	movlw	0x35
-	rcall	TFT_DataWrite
-	
-	movlw	0xC0
-	rcall	TFT_CmdWrite
-	movlw	0x2C
-	rcall	TFT_DataWrite
-	
-	movlw	0x2C
-	rcall	TFT_CmdWrite
-	movlw	0x01
-	rcall	TFT_DataWrite
+	movlw	LOW   display5_config_table
+	movwf	TBLPTRL
+	movlw	HIGH  display5_config_table
+	movwf	TBLPTRH
+	movlw	UPPER display5_config_table
+	movwf	TBLPTRU
+display45_init_loop:
+	TBLRD*+
+	movlw	0xFF				; coding for end of configuration
+	cpfseq	TABLAT				; TABLAT = 0xFF ?
+	bra	display45_config_write		; NO, write configuration to display
+	bra	display45_init_loop2		; YES - done
+display45_config_write:				; with command in WREG
+	movf	TABLAT,W
+	rcall	TFT_CmdWrite			; write command
+display45_config_write_more:
+	TBLRD*+					; get configuration
+	movf	TABLAT,W
+	rcall	TFT_DataWrite			; write configuration
+	movlw	0xFF				; coding for end of configuration
+	cpfseq	TABLAT
+	bra	display45_config_write_more
+	bra	display45_init_loop		; Continue with the next command
 	
-	movlw	0xC3
-	rcall	TFT_CmdWrite
-	movlw	0x11
-	rcall	TFT_DataWrite
-	
-	movlw	0xC4
-	rcall	TFT_CmdWrite
-	movlw	0x20
-	rcall	TFT_DataWrite
-	
-	movlw	0xC6
-	rcall	TFT_CmdWrite
-	movlw	0x0F
-	rcall	TFT_DataWrite
-	
-	movlw	0xD0
-	rcall	TFT_CmdWrite
-	movlw	0xA4
-	rcall	TFT_DataWrite
-	movlw	0xA1
-	rcall	TFT_DataWrite
-	; gamma
-	movlw	0x11
-	rcall	TFT_CmdWrite
-	
+display45_init_loop2:	
 	movlw	0x21
 	rcall	TFT_CmdWrite
 	WAITMS	d'60'
-	
 	movlw	0x29
 	rcall	TFT_CmdWrite
-	WAITMS	d'50'
+	WAITMS	d'120'
 	rcall	TFT_ClearScreen
-	; ToDo: Flip....
 	return			    ; done TFT_boot
 
+display4_config_table:
+	; Reg, Dat0, Dat1, Dat2, ... 0xFF for command end, 0xFF 0xFF for init end
+	db  0xB0,0x00,0xC4,0xFF,0xB1,0xC0,0xFF,0x3A
+	db  0x55,0xFF,0xB0,0x00,0xFF,0xB2,0x0C,0x0C
+	db  0x00,0x33,0x33,0xFF,0xB7,0x75,0xFF,0xBB
+	db  0x20,0xFF,0xC0,0x2C,0xFF,0xC2,0x01,0xFF
+	db  0xC3,0x19,0xFF,0xC4,0x20,0xFF,0xC6,0x0F
+	db  0xFF,0xD0,0xA7,0xA1,0xFF,0xBB,0x35,0xFF
+	db  0xC0,0x2C,0xFF,0xC2,0x01,0xFF,0xC3,0x11
+	db  0xFF,0xC4,0x20,0xFF,0xC6,0x0F,0xFF,0xD0
+	db  0xA7,0xA1,0xFF,0xBB,0x35,0xFF,0xC0,0x2C
+	db  0xFF,0x2C,0x01,0xFF,0xC3,0x11,0xFF,0xC4
+	db  0x20,0xFF,0xC6,0x0F,0xFF,0x11,0xFF,0xD0
+	db  0xA4,0xA1,0xC6,0x0F,0xFF,0x11,0xFF,0xFF
+	
+display5_config_table:
+	; Reg, Dat0, Dat1, Dat2, ... 0xFF for command end, 0xFF 0xFF for init end
+	db  0x13,0xFF,0xEF,0x01,0x01,0x00,0xFF,0xED
+	db  0x64,0x03,0x12,0x81,0xFF,0xE8,0x85,0x00
+	db  0x7A,0xFF,0xCB,0x39,0x2C,0x00,0x35,0x06
+	db  0xFF,0xEA,0x00,0x00,0xFF,0xC0,0x20,0xFF
+	db  0xC1,0x13,0xFF,0xC5,0x39,0x27,0xFF,0xC7
+	db  0xA6,0xFF,0x36,0x08,0xFF,0x3A,0x55,0xFF
+	db  0xB1,0x00,0x0B,0xFF,0xB6,0x08,0x82,0x27
+	db  0xFF,0xF2,0x00,0xFF,0x26,0x01,0xFF,0xFF
+	
 
 	global	TFT_CmdWrite
 TFT_CmdWrite:
@@ -938,6 +865,8 @@
 pixel_write_col320:
     	btfsc	screen_type4			; display type 4 ?
 	bra		pixel_write_col320_d4	; YES
+    	btfsc	screen_type5			; display type 5 ?
+	bra		pixel_write_col320_d4	; YES
 	btfsc	screen_type3			; display type 3 ?
 	bra		pixel_write_col320_d3	; YES
 	btfsc	screen_type2			; display type 2 ?
@@ -994,14 +923,20 @@
 	bra		TFT_DataWrite_PROD		; and return...
 
 pixel_write_col320_d4:
-    	movlw	0x2A
+    	movlw	0x2B
 	rcall	TFT_CmdWrite
-	rcall	TFT_DataWrite_PROD
+	movf	PRODH,W
+	rcall	TFT_DataWrite
+	movf	PRODL,W
+	rcall	TFT_DataWrite
 	incf	PRODL,F
 	movlw	.0
 	addwfc	PRODH,F					; +1
-	bra	TFT_DataWrite_PROD		; and return...	
-
+	movf	PRODH,W
+	rcall	TFT_DataWrite
+	movf	PRODL,W
+	bra	TFT_DataWrite				; and return
+	
 ;-----------------------------------------------------------------------------
 ; Write one half-pixel at position (win_top,win_leftx2).
 ; Inputs: win_leftx2, win_top, win_color_1/_2
@@ -1014,7 +949,9 @@
 half_pixel_write_1:
 	btfsc	screen_type4				; display type 4 ?
 	bra		half_pixel_write_1_display4	; YES
-        btfsc	screen_type3				; display type 3 ?
+	btfsc	screen_type5				; display type 5 ?
+	bra		half_pixel_write_1_display4	; YES
+	btfsc	screen_type3				; display type 3 ?
 	bra		half_pixel_write_1_display3	; YES
 	btfsc	screen_type2				; display type 2 ?
 	bra		half_pixel_write_1_display2	; YES
@@ -1109,7 +1046,7 @@
 half_pixel_write_1_display4:	
 	mullw	1						; copy row to PRODL (PRODH=0)
 	; Row address start
-	movlw	0x2B
+	movlw	0x2A
 	rcall	TFT_CmdWrite
 	movlw	0x00
 	rcall	TFT_DataWrite
@@ -1267,6 +1204,8 @@
 
 	btfsc	screen_type4			; screen type 4 ?
 	bra		TFT_box_write_display4	; YES
+	btfsc	screen_type5			; screen type 5 ?
+	bra		TFT_box_write_display4	; YES
 	btfsc	screen_type3			; screen type 3 ?
 	bra		TFT_box_write_display3	; YES
 	btfsc	screen_type2			; screen type 2 ?
@@ -1587,6 +1526,8 @@
 	movlw	0x22				; frame memory data write start
 	btfsc	screen_type4
 	movlw	0x2C				; Start Writing Data to GRAM (Display 4)
+	btfsc	screen_type5
+	movlw	0x2C				; Start Writing Data to GRAM (Display 4)
 	rcall	TFT_CmdWrite
 
 	clrf	PRODH					; column counter
@@ -1594,6 +1535,8 @@
 
 	btfsc	screen_type4			; display type 4 ?
 	bra		TFT_box_display4		; YES
+	btfsc	screen_type5			; display type 5 ?
+	bra		TFT_box_display4		; YES
 	btfsc	screen_type3			; display type 3 ?
 	bra		TFT_box_display3		; YES
 	btfsc	screen_type2			; display type 2 ?
--- a/src/tft_outputs.asm	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/tft_outputs.asm	Thu Nov 27 18:32:58 2025 +0100
@@ -677,16 +677,13 @@
 	global	TFT_surfmode_pres
 TFT_surfmode_pres:
 	; value
-	WIN_SMALL surf_press_column+.8,surf_press_row
+	WIN_SMALL surf_press_column+.6,surf_press_row
 	FONT_COLOR_MEMO						; set color
 	SMOVII	pressure_abs,mpr			; get current pressure
 	FONT_COLOR_MEMO						; print in standard color
 	output_9999							; print (0-9999)
-	PRINT								; dump buffer to screen
-	; unit
-	WIN_SMALL	surf_press_column+(4+1)*8,surf_press_row
-	FONT_COLOR_MASK						; switch to mask color
-	STRCPY_TEXT_PRINT tMBAR				; print unit (hPa)
+	PUTC	" "
+	STRCAT_TEXT_PRINT tMBAR				; print unit (hPa)
 	return								; done
 
 
@@ -697,7 +694,7 @@
 TFT_surfmode_temp:
 	; unit
 	WIN_SMALL surf_temp_column+3*8,surf_temp_row
-	FONT_COLOR_MASK						; select mask color
+	FONT_COLOR_MEMO						; print in standard color
 	TSTOSS	opt_units					; 0=°C, 1=°F
 	bra		TFT_temp_surfmode_metric	; 0: metric
 	;bra	TFT_temp_surfmode_imperial	; 1: imperial
@@ -783,6 +780,27 @@
 	STRCAT_PRINT "% "					; append unit with trailing space and dump to screen
 
 	WIN_TINY batt_voltage_column+.15,batt_voltage_row
+	btfss	dn_flag
+	bra	TFT_surfmode_batt2
+	WIN_TINY batt_voltage_column+.15,.5
+	FONT_COLOR color_green				; set menu title font color
+	STRCPY_TEXT_PRINT tBattery
+	return
+TFT_surfmode_batt2:	
+	FONT_COLOR_MEMO						; set color
+	movff	battery_type,lo				; get battery type
+	PUTC	"T"							; print "T"
+	output_9							; print battery type code (0-9)
+	PUTC	":"							; print ":"
+	MOVII	batt_voltage,mpr			; get battery voltage
+	bsf		omit_digit_2				; do not print 2nd and 1st digit
+	bsf		decimal_digit3				; place a decimal point in front of digit 3
+	output_9999							; print x.x--
+	PUTC_PRINT 'V'						; append unit and dump to screen
+	return								; done
+	
+	
+	WIN_TINY batt_voltage_column+.15,batt_voltage_row
 	FONT_COLOR_MEMO						; set color
 	movff	battery_type,lo				; get battery type
 	PUTC	"T"							; print "T"
@@ -821,7 +839,7 @@
 	global	TFT_surfmode_decotype
 TFT_surfmode_decotype:
 	WIN_STD surf_decotype_column,surf_decotype_row
-	FONT_COLOR color_lightblue			; set font color
+	FONT_COLOR	color_green			; set font color
 	movff	opt_dive_mode,lo			; get deco mode 
 	tstfsz	lo							; in OC mode?
 	bra		TFT_decotype_surface_2		; NO
@@ -849,10 +867,10 @@
 	; Sensor or Auto SP mode
 	sublw	.2							; ccr_mode = 2 (Auto SP) ?
 	bz		TFT_decotype_surface_cc_auto; YES - AutoSP
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	STRCPY_TEXT tCCRModeSensor			; NO  - print "Sensor"
 	bra		TFT_decotype_surface_cc_com	;     - continue
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 TFT_decotype_surface_cc_auto:
 	STRCPY_TEXT tCCRModeAutoSP			; print "Auto SP"
@@ -1160,7 +1178,7 @@
 	bsf	aux_flag			; PM/AM Bit
 	return
     
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Surface Mode - Imprint ppO2 from Sensors
@@ -1246,6 +1264,8 @@
 	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row+.24
 	btfsc	ext_input_optical			; optical input?
 	bra		TFT_sensor_mV_optical		; YES
+	btfsc	ext_s8_full_digital			; are we in external S8 full digital mode? 
+	bra		TFT_sensor_mV_optical		; YES
 	TSTOSS	opt_s8_mode					; NO  - S8 input selected?
 	bra		TFT_sensor_mV_analog		;       NO  - analog input
 	;bra	TFT_sensor_mV_s8			;       YES - S8
@@ -1376,7 +1396,7 @@
 	STRCAT_PRINT "mV"					; append unit and dump buffer to screen
 	return								; done
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
 
  IFDEF _rx_functions
@@ -1696,7 +1716,7 @@
 	bra		TFT_depth_exit_2			;             YES
 	;bra	TFT_depth_exit_1			;             NO
 
-TFT_depth_exit_1
+TFT_depth_exit_1:
 	WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row
 	FONT_COLOR_MASK						; set color
 	STRCAT_TEXT_PRINT tDepth			; restore "Depth" title
@@ -2035,11 +2055,15 @@
 
 	WIN_SMALL dm_temp_column,dm_temp_row; set position
 	FONT_COLOR_MEMO						; set color
-	movlw	index_compass_dm			; index of compass custom view
-	cpfseq	active_customview			; compass shown in custom view?
-	goto	TFT_temp_common				; NO  - continue with common part for temperature
-	goto	TFT_update_stopwatch		; YES - show resettable dive time instead of temperature
-
+	goto	TFT_temp_common				; continue with common part for temperature
+
+	global	TFT_dive_compass_extras
+TFT_dive_compass_extras:			; Update Stopwatch display in compass mode
+	WIN_SMALL dm_compass_stopwatch_column,dm_compass_stopwatch_row	; set position
+	FONT_COLOR_MEMO					; set color
+	MOVII	divesecs_compass_trip,mpr		; get the compass stopwatch
+	goto	update_stopwatch_common		; YES - show resettable dive time instead of temperature (And return)
+	
 
 ;-----------------------------------------------------------------------------
 ; Dive Mode - active Gas and Setpoint
@@ -2099,7 +2123,7 @@
 	FONT_COLOR_MEMO						; select memo color
 	STRCAT	"bar"						; print "bar"
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 	movf	dive_ccr_mode,W				; get setpoint mode =0: Fixed SP, =1: Sensor, =2: Auto SP
 	sublw	.1							; dive_ccr_mode = 1 (Sensor) ?
@@ -2942,12 +2966,15 @@
 	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	STRCPY	"I2C "						; print "I2C Error:"
+	STRCPY	"I: "						; print "I2C Error:"
 	movff	i2c_error_vault+0,WREG				; last device adress
 	output_hex
 	PUTC	" "
 	movff	i2c_error_vault+1,WREG				; last data byte 
 	output_hex
+	PUTC	" "
+	movff	i2c_error_vault+2,WREG				; copy of SSP1CON2
+	output_hex
 	bra		TFT_message_close			; finalize message output
 
 ;-----------------------------------------------------------------------------
@@ -3481,7 +3508,7 @@
 
  ENDIF	; _ccr_pscr
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Dive Mode - Message - Sensor ppO2 Divergence
@@ -3510,7 +3537,7 @@
 	STRCPY_TEXT tDiveFallback			; print "Fallback!"
 	bra		TFT_message_close			; finalize message output
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
  IFDEF _rx_functions
 
@@ -3627,21 +3654,66 @@
 	
 	global	TFT_surf_desat_nofly_cns
 TFT_surf_desat_nofly_cns:
-	WIN_SMALL surf_gaslist_column+.10,surf_gaslist_row+.5
-	call	TFT_surf_mesg_desat2
-	WIN_SMALL surf_gaslist_column+.10,surf_gaslist_row+(surf_gaslist_spacing*.1)+.5
-	call	TFT_nofly_time_fly
-	WIN_SMALL surf_gaslist_column+.10,surf_gaslist_row+(surf_gaslist_spacing*.2)+.5
-	bra	TFT_surface_tissues_5		; continue
-	
+    	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+.5
+	STRCPY_PRINT	"Desat:"			; print label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.56,surf_gaslist_row
+	MOVII	int_O_desaturation_time,mpr	; get desaturation time in minutes
+	rcall	TFT_surf_desat_nofly_cns_helper
+
+	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)+.5
+	movff	char_I_altitude_wait,WREG	; get mode
+	tstfsz	WREG					; mode = altitude?
+	bra		TFT_surf_desat_nofly_cns_noalt	; YES
+	;bra	TFT_nofly_time_fly			; NO
+
+TFT_surf_desat_nofly_cns_nofly:
+	STRCPY_PRINT	"NoFly:"					; print no-fly label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.56,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	MOVII	int_O_nofly_time,mpr		; get no-fly time in minutes
+	rcall	TFT_surf_desat_nofly_cns_helper
+	bra	TFT_surf_desat_nofly_cns2			; continue
+
+TFT_surf_desat_nofly_cns_noalt:
+	STRCPY_PRINT	"NoAlt:"					; print no-altitude label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.56,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	rcall	TFT_surf_desat_nofly_cns_helper
+	;bra	TFT_surf_desat_nofly_cns2			; continue
+
+TFT_surf_desat_nofly_cns2:
+       	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)+.5
+	STRCPY_PRINT	"CNS:"			; print label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.62,surf_gaslist_row+(surf_gaslist_spacing*.2)
+	MOVII	int_O_CNS_current,mpr		; get current CNS
+	call	TFT_color_code_cns			; color-code CNS value
+	output_999							; print (0-999)
+	PUTC_PRINT "%"						; append unit and dump to screen
+	return
+		
+TFT_surf_desat_nofly_cns_helper:	
+	call	convert_time				; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
+	movff	lo,up						; backup lo
+	movff	hi,lo						; get   hours into lo
+	output_99							; print hours (0-99)
+	PUTC	':'							; print ":"
+	movff	up,lo						; get   minutes into lo
+	output_99x							; print minutes (00-99)
+	PRINT
+	return
 	
 ;-----------------------------------------------------------------------------
 ; Surface Custom View - Last Dive Summery
 ;
 	global	TFT_surf_cv_lastdive
 TFT_surf_cv_lastdive:
-	FONT_COLOR_MEMO						; set color
-
+	FONT_COLOR color_green				; set menu title font color
+	
 	WIN_TINY surf_gaslist_column,surf_gaslist_row+.5
 	STRCAT_TEXT_PRINT	tLastDive		; "Last Dive:"
 
@@ -3654,6 +3726,7 @@
 	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)+.5
 	STRCAT_TEXT_PRINT	tAvgDepth		; "Average"
 
+	FONT_COLOR_MEMO						; set color
 	WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row
 	SMOVII	int_O_desaturation_time,mpr	; ISR-safe copy of the desaturation time
 	movf	mpr+0,W						; get low byte into WREG
@@ -4010,9 +4083,16 @@
 ;
 	global	TFT_surf_cv_settings
 TFT_surf_cv_settings:
+    	FONT_COLOR color_green				; set menu title font color
+	
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+.5
+	STRCAT_TEXT	tGasDeco		; "Deco"
+	PUTC	":"
+	PRINT
+
 	; Deco Mode
 	FONT_COLOR_MEMO						; select color
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row
+	WIN_SMALL surf_gaslist_column+.27,surf_gaslist_row
 	STRCAT_PRINT "ZH-L16"				; print fix part of model
 	movff	char_I_model,WREG			; get model
 	iorwf	WREG						; GF enabled?
@@ -4021,20 +4101,25 @@
 
 TFT_surface_decosettings0:
 	; Display ZH-L16 sat/desat model
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	STRCPY_TEXT tSD								; print label (S/D)
+	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)+.5
+	STRCPY_TEXT_PRINT tSD								; print label (S/D)
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.27,surf_gaslist_row+(surf_gaslist_spacing*.1)
 	movff	char_I_saturation_multiplier,  lo	; get sat   mult.
 	movff	char_I_desaturation_multiplier,hi	; get desat mult.
 	bra		TFT_surface_decosettings_com		; continue with common part
 
 TFT_surface_decosettings1:
 	; Display ZH-L16-GF low/high model
-	WIN_SMALL surf_gaslist_column+.43,surf_gaslist_row
-	STRCPY_TEXT_PRINT tZHL16GF					; print GF label behind deco model label
-
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	STRCPY_TEXT tGF								; print label (GF:)
-	PUTC	' '									; print a space
+	WIN_SMALL surf_gaslist_column+.43+.27,surf_gaslist_row
+	STRCPY_TEXT_PRINT tZHL16GF					; print "+GF" label behind deco model label
+	
+	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)+.5
+	STRCPY_TEXT_PRINT tGF								; print label (GF:)
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.27,surf_gaslist_row+(surf_gaslist_spacing*.1)
 	movff	opt_GF_low, lo						; get GF low
 	movff	opt_GF_high,hi						; get GF high
 	;bra	TFT_surface_decosettings_com		; continue with common part
@@ -4048,26 +4133,34 @@
 	PUTC_PRINT "%"						; append unit and dump to screen
 
 	; fTTS
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	STRCPY_TEXT tFTTSSurf				; print label
+	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)+.5
+	STRCPY_TEXT_PRINT tFTTSSurf				; print label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.76,surf_gaslist_row+(surf_gaslist_spacing*.2)
 	movff	char_I_extra_time,lo		; get time
 	output_9							; print time (0-9)
 	STRCAT_TEXT_PRINT tMinutes			; append unit and dump to screen
 
 	; Last Stop
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
-	STRCPY_TEXT tLastDecostopSurf		; print label
+	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)+.5
+	STRCPY_TEXT_PRINT tLastDecostopSurf		; print label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.76,surf_gaslist_row+(surf_gaslist_spacing*.3)
 	movff	opt_last_stop,lo			; get depth
 	output_9							; print depth (0-9)
 	STRCAT_TEXT_PRINT tMeters			; append unit and dump to screen
 
 	; Salinity
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
-	STRCPY_TEXT tDvSalinitySurf			; print label
+	FONT_COLOR color_green				; set menu title font color
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)+.5
+	STRCPY_TEXT_PRINT tDvSalinitySurf			; print label
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column+.76,surf_gaslist_row+(surf_gaslist_spacing*.4)
 	movff	opt_salinity,lo				; get salinity
 	output_9							; print salinity (0-9)
 	STRCAT_TEXT_PRINT tPercent			; append unit and dump to screen
-
 	return								; done
 
 
@@ -4436,8 +4529,8 @@
 	;bra	TFT_update_stopwatch		; continue
 
 TFT_update_stopwatch:
-	; jump-in point for stopped dive time in compass custom view
-	MOVII	divesecs_avg_trip,mpr		; get the resettable dive time (stopwatch)
+    	MOVII	divesecs_avg_trip,mpr		; get the resettable dive time (stopwatch)
+update_stopwatch_common:				; jump-in point for stopped dive time in compass custom view
 	call	convert_time				; convert hi:lo in seconds to minutes (up:hi) and seconds (lo)
 	movlw	.100						; display layout will change if minutes become >= 100
 	cpfslt	hi							; minutes < 100 ?
@@ -4705,46 +4798,40 @@
 TFT_ceiling_GF_tissue_mask:
 	FONT_COLOR_MASK						; select color
 
+	WIN_TINY dm_custom_gf_column1+.5, dm_custom_gf_title_row
+	STRCPY_TEXT_PRINT tGFInfo			; print label
+	
 	WIN_TINY dm_custom_ceiling_column+.2,dm_custom_ceiling_title_row
 	STRCPY_TEXT_PRINT tCeiling			; print label
 
 	WIN_TINY dm_custom_tissue_title_column, dm_custom_tissue_title_row
-	STRCPY_TEXT_PRINT tDiveTissues		; print label
+	STRCPY_TEXT_PRINT tDiveTissues		; print labelGF
+	return								; done
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Ceiling, Supersaturation & GF Surface - Mask
+;
+	global	TFT_ceiling_GF_surfGF_mask
+TFT_ceiling_GF_surfGF_mask:
+	FONT_COLOR_MASK						; select color
 
 	WIN_TINY dm_custom_gf_column1+.5, dm_custom_gf_title_row
 	STRCPY_TEXT_PRINT tGFInfo			; print label
 
-	return								; done
-
+	WIN_TINY dm_custom_ceiling_column+.2,dm_custom_ceiling_title_row
+	STRCPY_TEXT_PRINT tCeiling			; print label
+
+	WIN_TINY dm_custom_surfGF_title_column, dm_custom_surfGF_title_row
+	STRCPY_TEXT_PRINT tDiveSurfGF		; print label
+	return								; done	
 
 ;-----------------------------------------------------------------------------
 ; Dive Custom View - Ceiling, Supersaturation & Tissues - Data
 ;
 	global	TFT_ceiling_GF_tissue
 TFT_ceiling_GF_tissue:
-	WIN_MEDIUM dm_custom_ceiling_column,dm_custom_ceiling_row
-	MOVII	int_O_ceiling,mpr			; get ceiling in [mbar] relative pressure
-	call	TFT_color_code_ceiling		; color-code the output (also strips off flags)
-	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
-
-	TSTOSS	opt_units						; 0=m, 1=ft
-	bra		TFT_ceiling_GF_tissue_metric	; 0 - meter
-	;bra	TFT_ceiling_GF_tissue_imperial	; 1 - feet
-
-TFT_ceiling_GF_tissue_imperial:
-	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
-	output_999							; print (0-999)
-	bra		TFT_ceiling_GF_tissue0		; continue
-
-TFT_ceiling_GF_tissue_metric:
-	bsf		omit_digit_1				; do not print 1st digit
-	bsf		decimal_digit2				; place a decimal point in front of digit 2
-	bsf		leftbind					; print left-aligned
-	output_65535						; print (xxx.x-)
-	bra		TFT_ceiling_GF_tissue0		; continue
-
-TFT_ceiling_GF_tissue0:
-	PUTC_PRINT " "						; append a space and dump to screen
+    	; Show ceiling
+	rcall	TFT_ceiling
 	; show tissue diagram
 	rcall	TFT_dive_tissues			; show tissue pressure diagram
 	; show current supersaturation
@@ -4757,7 +4844,6 @@
 	PUTC_PRINT "%"						; print "%" and dump to screen
 	return								; done
 
-
 	;-------------------------------------------------------------------------
 	; Draw saturation graph in dive mode custom view
 	;
@@ -4907,6 +4993,31 @@
 	PRINT								; dump buffer to screen
 	return								; done
 
+TFT_ceiling:    
+	WIN_MEDIUM dm_custom_ceiling_column,dm_custom_ceiling_row
+	MOVII	int_O_ceiling,mpr			; get ceiling in [mbar] relative pressure
+	call	TFT_color_code_ceiling		; color-code the output (also strips off flags)
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
+
+	TSTOSS	opt_units						; 0=m, 1=ft
+	bra		TFT_ceiling_GF_tissue_metric	; 0 - meter
+	;bra	TFT_ceiling_GF_tissue_imperial	; 1 - feet
+
+TFT_ceiling_GF_tissue_imperial:
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	output_999							; print (0-999)
+	bra		TFT_ceiling_GF_tissue0		; continue
+
+TFT_ceiling_GF_tissue_metric:
+	bsf		omit_digit_1				; do not print 1st digit
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	bsf		leftbind					; print left-aligned
+	output_65535						; print (xxx.x-)
+	bra		TFT_ceiling_GF_tissue0		; continue
+
+TFT_ceiling_GF_tissue0:
+	PUTC_PRINT " "						; append a space and dump to screen
+	return	
 
 	; Helper Function - draw a bargraph
 TFT_dive_tissues_bargraph:
@@ -4924,6 +5035,32 @@
 	BOX_COLOR							; draw bargraph
 	return								; done
 
+;-----------------------------------------------------------------------------
+; Dive Custom View - Ceiling, Supersaturation & Surf GF - Data
+;
+	
+	global	TFT_ceiling_GF_surfGF
+TFT_ceiling_GF_surfGF:				; data for ceiling, current GF and Surf GF
+	; Show ceiling
+	rcall	TFT_ceiling
+	; show current supersaturation
+	WIN_MEDIUM dm_custom_clock_column+.3, dm_custom_gf_row
+	MOVII	int_O_lead_supersat,mpr		; bank-safe copy of leading tissue's supersaturation
+	call	TFT_color_code_supersat		; color-code output
+	output_256							; need to print lo only, int_O_lead_supersat value is limited to 255
+	PRINT								; dump to screen
+	WIN_STD	dm_custom_clock_column+.40, dm_custom_gf_row+.5
+	PUTC_PRINT "%"						; print "%" and dump to screen
+	; show Surface GF
+	WIN_MEDIUM dm_custom_gf_column3+.13, dm_custom_gf_row
+	MOVII	int_O_GF_surface,mpr		; bank-safe copy of leading tissue's supersaturation
+	FONT_COLOR_MEMO							; set color
+	output_999
+	PRINT								; dump to screen
+	WIN_STD	dm_custom_gf_column3+.50, dm_custom_gf_row+.5
+	PUTC_PRINT "%"						; print "%" and dump to screen
+
+	return		
 
 ;-----------------------------------------------------------------------------
 ; Dive Custom View - CNS - Mask
@@ -5371,7 +5508,7 @@
 
  ENDIF	; _ccr_psrc
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 
 ;-----------------------------------------------------------------------------
 ; Dive Custom View - Sensor ppO2 - Mask
@@ -5547,7 +5684,7 @@
 TFT_ppo2_sensors_4:
 	return								; done
 
- ENDIF	; _external_sensor
+ ENDIF	; _external_sensor_eccr
 
  IFDEF _rx_functions
 
@@ -6161,7 +6298,7 @@
 TFT_print_decotype:
 	bsf		aux_flag					; default to dive with deco calculation (used by logbook)
 	incf	lo,W						; WREG = lo + 1
-TFT_print_decotype_1
+TFT_print_decotype_1:
 	decfsz	WREG,W						; in OC mode?
 	bra		TFT_print_decotype_2		; NO  - try next
 	STRCAT_TEXT_PRINT tDvOC				; YES - print "OC"
@@ -6209,10 +6346,13 @@
 ;	WIN_TINY   .0, .		0					; dive    mode: overwrites depth label
 	FONT_COLOR_MEMO								; set color
 	
+	;movff	ambient_light+0,lo
 	movff	gp_debug+0,lo
-	output_256
+	movff	gp_debug+1,hi
+	output_65535
 	PUTC	","
-	movff	gp_debug+1,lo
+	movff	ambient_light+0,lo
+;	movff	gp_debug+1,lo
 	output_256
 
 	;	; deco engine scheduling performance
--- a/src/tft_outputs.inc	Mon Apr 29 13:05:18 2024 +0200
+++ b/src/tft_outputs.inc	Thu Nov 27 18:32:58 2025 +0100
@@ -65,7 +65,7 @@
 	extern	TFT_imprint_color_schemes			; imprint color schemes (animated dive time)
 	extern	TFT_convert_lo_into_12h_format			; converts lo (0-23h) into lo (1-12) with PM/AM flag in aux_flag
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	extern	TFT_imprint_menu_mV					; imprint sensor data in menu    mode - mv
 	extern	TFT_imprint_surf_ppO2				; imprint sensor data in surface mode - ppO2
 	extern	TFT_imprint_surf_mV					; imprint sensor data in surface mode - mV
@@ -110,6 +110,10 @@
 
 	extern	TFT_safety_stop_show				; show  safety stop
 	extern	TFT_safety_stop_clear				; clear safety stop
+	
+ IFDEF _compass
+	extern	TFT_dive_compass_extras				; Update Stopwatch display in compass mode
+ ENDIF
 
 
 ;-----------------------------------------------------------------------------
@@ -139,7 +143,7 @@
 	extern	TFT_message_gas_density				; gas density
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	extern	TFT_message_divergence				; sensor ppO2 divergence
 	extern	TFT_message_fallback				; show fallback warning
  ENDIF
@@ -167,6 +171,8 @@
 	extern	TFT_decoplan						; data for deco plan
 	extern	TFT_ceiling_GF_tissue_mask			; mask for ceiling, current GF and tissues
 	extern	TFT_ceiling_GF_tissue				; data for ceiling, current GF and tissues
+	extern	TFT_ceiling_GF_surfGF_mask			; mask for ceiling, current GF and Surf GF
+	extern	TFT_ceiling_GF_surfGF				; data for ceiling, current GF and Surf GF
 	extern	TFT_CNS_mask						; mask for CNS values
 	extern	TFT_CNS								; data for CNS values
 	extern	TFT_ppo2_ead_end_cns_mask			; mask for ppO2, END/EAD and CNS / gas density
@@ -183,7 +189,7 @@
 	extern	TFT_pscr_info						; data for pSCR info
  ENDIF
 
- IFDEF _external_sensor
+ IFDEF _external_sensor_eccr
 	extern	TFT_ppo2_sensors_mask				; mask for ppO2 sensors
 	extern	TFT_ppo2_sensors					; data for ppO2 sensors
  ENDIF