view src/start.asm @ 622:02d1386429a6

0x60 added for (future) option to change logbook offset via PC/Bluetooth
author heinrichsweikamp
date Wed, 10 Apr 2019 10:51:07 +0200
parents b87f23fae743
children c40025d8e750
line wrap: on
line source

;=============================================================================
;
;   File start.asm									REFACTORED VERSION	V2.99g
;
;   Startup subroutines
;
;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
;=============================================================================
; HISTORY
;  2011-08-06 : [mH] moving from OSTC code

#include "hwos.inc"							; mandatory header
#include "ms5541.inc"
#include "isr.inc"
#include "shared_definitions.h"				; mailbox from/to p2_deco.c
#include "eeprom_rs232.inc"
#include "math.inc"
#include "tft.inc"
#include "surfmode.inc"
#include "wait.inc"
#include "rtc.inc"
#include "external_flash.inc"
#include "convert.inc"
#include "strings.inc"
#include "tft_outputs.inc"
#include "adc_lightsensor.inc"
#include "i2c.inc"

	extern	init_ostc
	extern	option_restore_all
	extern	restore_decodata_from_eeprom
	extern	oPressureAdjust
	extern	option_reset
	extern	option_save
	extern	option_save_all
	extern	option_check_all
	extern	do_new_battery_select
	extern	use_old_batteries
	extern	use_old_prior_209
	extern	get_first_gas_to_WREG
	extern	get_first_dil_to_WREG
	extern	option_cleanup_oCCRMode_pSCR
	extern	option_cleanup_oCCRMode_CCR

 IFDEF _rx_functions
	extern	option_cleanup_oTrMode_CCR
	extern	option_cleanup_oTrMode_no_CCR
 ENDIF


;=============================================================================
; Reset Vector: entry point on device wake-up and hard reset
;
reset_v code 0x00000

;	goto	start
	goto	0x1FF00							; bootloader

	ORG		0x00004							; needed for second-level bootloader
	goto	start

;=============================================================================

boot		CODE

;=============================================================================

	global	start
start:
	lfsr	FSR0,0x000						; clear ram-banks 0-14
clear_rambank:
	clrf	POSTINC0
	movlw	0x0F
	cpfseq	FSR0H							; bank 14 done?
	bra		clear_rambank					; NO - loop

	call	init_ostc						; initialize hardware (ports, timers, etc.)

	; get button type from Bootloader-Info
	movlw	.16
	movff	WREG,analog_counter				; initialize averaging
	bsf		analog_switches
	movlw	0x7C
	movwf	TBLPTRL
	movlw	0xF7
	movwf	TBLPTRH
	movlw	0x01
	movwf	TBLPTRU
	TBLRD*+									; reads 0x07 for analog buttons
	movlw	0x07
	cpfseq	TABLAT
	bcf		analog_switches

	; get screen type (2) from Bootloader-Info
	bsf	screen_type2
	movlw	0x80
	movwf	TBLPTRL							; only adjust low byte, high and upper are still 0x01F7...
	TBLRD*+									; reads 0x83 if OSTC has screen type 2
	movlw	0x83
	cpfseq	TABLAT
	bcf		screen_type2

	; read button polarity
	movlw	LOW  .897
	movwf	EEADR
	movlw	HIGH .897
	movwf	EEADRH
	call	read_eeprom						; EEDATA into EEPROM @ EEADR
	clrf	EEADRH							; reset EEADRH
	movff	EEDATA,button_polarity			; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only)

	; air pressure compensation after reset
	call	get_calibration_data			; get calibration data from pressure sensor
	banksel	common							; get_calibration_data uses isr_backup

	call	TFT_DisplayOff					; turn off display
	bsf		LEDr							; turn on  red LED
	bcf		pressure_refresh
	; first pass will not have valid temperature
	btfss	pressure_refresh				; air pressure compensation
	bra		$-2
	; second pass
	bcf		pressure_refresh
	btfss	pressure_refresh				; air pressure compensation
	bra		$-2
	bcf		LEDr

	clrf	rel_pressure+0
	clrf	rel_pressure+1
	clrf	surface_interval+0
	clrf	surface_interval+1

	SAFE_2BYTE_COPY amb_pressure, last_surfpressure

	movlw	LOW  max_surfpressure
	movff	WREG,sub_a+0					; max. "allowed" air pressure in mbar
	movlw	HIGH max_surfpressure
	movff	WREG,sub_a+1					; max. "allowed" air pressure in mbar
	movff	last_surfpressure+0,sub_b+0
	movff	last_surfpressure+1,sub_b+1
	call	subU16							; sub_c = sub_a - sub_b
	btfss	neg_flag						; is 1080 mbar < amb_pressure ?
	bra		start_copy_pressure				; NO - current air pressure is lower then "allowed" air pressure, ok

	; not ok - overwrite with max. "allowed" air pressure
	movlw	LOW  max_surfpressure
	movff	WREG,last_surfpressure+0		; max. "allowed" air pressure in mbar
	movlw	HIGH max_surfpressure
	movff	WREG,last_surfpressure+1		; max. "allowed" air pressure in mbar

start_copy_pressure:
	movff	last_surfpressure+0,last_surfpressure_15min+0
	movff	last_surfpressure+1,last_surfpressure_15min+1
	movff	last_surfpressure+0,last_surfpressure_30min+0
	movff	last_surfpressure+1,last_surfpressure_30min+1	; resets all air pressure registers

	; initialize GF high (needed by deco engine for color-coding the GF value)
	movff	opt_GF_high,char_I_GF_High_percentage

	SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration		; breathing at surface
	movff	int_I_pres_respiration+0,int_I_pres_surface+0	; surface pressure
	movff	int_I_pres_respiration+1,int_I_pres_surface+1

	call	deco_clear_tissue				; set all tissues to Pamb * N2_ratio (code located in p2_deco.c)
	banksel	common							; back to bank 1, needed after every return from C code

	call	rtc_init						; init clock

	movlw	HIGH .512						; =2
	movwf	EEADRH
	read_int_eeprom	.0
	clrf	EEADRH
	movlw	0xAA
	cpfseq	EEDATA							; =0xAA
	bra		no_deco_restore					; NO
	call	restore_decodata_from_eeprom	; reload deco data and date/time from eeprom
no_deco_restore:
	call	deco_calc_dive_interval_1min	; calculate deco in surface mode
	call	deco_calc_desaturation_time		; calculate desaturation and no-fly time
	banksel	common

	bcf		menubit							; clear menu flag

	; check for power-on reset here

	; *****************************************************************************
	; "do_new_battery_menu" and "use_old_batteries" 'goto' back to "power_on_return"
	; *****************************************************************************

	; Try to migrate the old battery status from firmware 2.09 or earlier..
	btfsc	RCON,POR						; was this a power-on reset?
	call	use_old_prior_209				; NO

	bcf		use_old_batt_flag
	btfsc	RCON,POR						; was this a power-on reset?
	bsf		use_old_batt_flag				; NO
 
	call	lt2942_get_status				; check for gauge IC
	btfss	battery_gauge_available			; cR or 2 hardware?
	bra		check_firmware_new				; NO  - skip next
	movlw	.30								; YES - reset button sensitivity
	movff	WREG,opt_cR_button_right
	movff	WREG,opt_cR_button_left			; reset on power-on reset
	call	piezo_config					; configure buttons
	call	piezo_config					; configure buttons (2 times)

check_firmware_new:
	call	TFT_boot						; initialize TFT (includes clear screen)
	clrf	CCPR1L							; backlight off

	WIN_TOP  .40
	WIN_LEFT .10
	TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block ; show heinrichsweikamp logo

	call	TFT_standard_color

	WIN_SMALL .20,.100
	STRCPY_PRINT "Update successful!"		; hard coded since language switch does not work here

	WIN_SMALL .20,.140
	STRCPY	"New Firmware: "
	call	TFT_cat_firmware				; show firmware version x.y and color-code if outdated
	STRCAT_PRINT ""							; finalize output
	bcf		win_invert						; reset inverted output if firmware is outdated
	call	TFT_standard_color				; reset color           if firmware is outdated

	WIN_SMALL .60,.180
	call	TFT_cat_beta_release			; if it is a beta version, show "BETA" + issue, else "Release"
	STRCAT_PRINT ""							; finalize output
	call	TFT_standard_color				; reset color

	call	TFT_Display_FadeIn				; display resulting surface screen

	; check if a new firmware was loaded, if yes reset Custom Function oPressureAdjust
	movlw	d'1'
	movwf	EEADR							; =1
	movwf	EEADRH							; =1
	call	read_eeprom						; read current version x
	movff	EEDATA,lo
	incf	EEADR,F							; set to 0x102
	call	read_eeprom						; read current version y
	movff	EEDATA,hi
	clrf	EEADRH							; reset EEADRH

	movlw	softwareversion_x
	cpfseq	lo								; compare version x
	bra		check_firmware_new4				; is not equal -> reset CF and store new version in EEPROM

	movlw	softwareversion_y
	cpfseq	hi								; compare version y
	bra		check_firmware_new4				; is not equal -> reset CF and store new version in EEPROM
	bra		check_firmware_new5				; x and y are equal -> do not reset CF

check_firmware_new4:
	; place "after-update reset" here...
	lfsr	FSR0,oPressureAdjust
	call	option_reset					; reset oPressureAdjust to factory default
	lfsr	FSR0,oPressureAdjust
	call	option_save						; save new value of oPressureAdjust in EEPROM

check_firmware_new5:
	rcall	backup_flash_page				; backup the first 128 bytes from flash to EEPROM

	movlw	d'1'							; store current version in EEPROM
	movwf	EEADR							; =1
	movwf	EEADRH							; =1
	movlw	softwareversion_x
	movwf	EEDATA
	call	write_eeprom					; write version, major number
	incf	EEADR,F							; set to 0x102
	movlw	softwareversion_y
	movwf	EEDATA
	call	write_eeprom					; write version, minor number
	clrf	EEADRH							; reset EEADRH

	; wait 10 seconds
	movlw	.10								; load loop counter
check_firmware_new6:
	call	wait_1s							; wait (about) 1 second
	decfsz	WREG,W							; YES - decrement loop counter, did it became zero?
	bra		check_firmware_new6				;       NO  - loop
	;bra	restart							;       YES - proceed with restart


	global	restart
restart:
	clrf	STKPTR							; never return from here
	clrf	CCP1CON							; stop PWM
	bcf		PORTC,2							; pull PWM out to GND

	btfsc	menubit							; return from Menu/COMM mode or timeout?
	call	option_save_all					; YES - save all settings into EEPROM

	call	option_restore_all				; restore everything from EEPROM into RAM
	call	option_check_all				; check all options (and reset if not within their min/max boundaries)
	call	option_save_all					; save all settings into EEPROM after they have been checked

	clrf	flag1							; clear all flags
	clrf	flag2
	clrf	flag3
	clrf	flag4
	clrf	flag5
	clrf	flag6
	clrf	flag7
	clrf	flag8
	clrf	flag9
	clrf	flag10 ; Clears flag "enable_screen_dumps" - making screen dumps impossible... TODO
	; do not clear flag11 (sensor calibration and charger status)
	clrf	flag12
	; do not clear flag13 (important hardware flags)
	clrf	flag14
	clrf	flag15
	clrf	flag16
	clrf	flag17
	; do not clear flag18 (important hardware flags)
	
	clrf	cvt_flags

	clrf	tft_update_flags+0
	clrf	tft_update_flags+1
	clrf	tft_update_flags+2

	clrf	hardware_flag1					; hardware descriptor 1
	;		hardware_flag2					; hardware descriptor 2 - do not clear here!

	bsf		tft_is_dimming					; TFT is dimming up (soon), ignore ambient sensor!

	; configure hardware descriptor 1
	bcf		tft_power						; inverted, here needed for I2C_probe_OSTC_rx, to wake-up RX circuity
	bsf		ambient_sensor					; set flag
	bsf		optical_input					; set flag

	call	lt2942_get_status				; check for gauge IC
	btfss	battery_gauge_available			; cR/2 hardware?
	bra		restart2						; NO
	call	lt2942_init						; YES - initialize battery gauge IC
	bcf		optical_input					; clear flag

	banksel	0xF16
	bcf		ANCON0,7						; AN7 digital input
	banksel	common
	bcf		lightsen_power					; power-down ambient light sensor
	bcf		ambient_sensor					; clear flag
	nop
	btfss	PORTF,2							; light sensor available?
	bsf		ambient_sensor					; YES
	banksel	0xF16
	bsf		ANCON0,7						; AN7 analog again
	banksel	common
	bsf		lightsen_power					; power-up ambient light sensor again

restart2:
	btfsc	vusb_in
	bra		restart3						; USB (and powered on)
	bcf		PORTE,0							; start comms
	WAITMS	d'5'
	btfss	vusb_in
	bra		restart3						; USB (and powered off)
	bsf		ble_available					; BLE available

restart3:
	bsf		PORTE,0							; stop comms
	btfsc	ble_available					; BLE available?
	bra		restart4						; YES - can't be a cR
	btfss	battery_gauge_available			; rechargeable?
	bra		restart4						; NO  - can't be a cR
	bsf		analog_o2_input					; set flag for analog

restart4:
 IFDEF _rx_functions
	WAITMS	d'200'
	call	I2C_probe_OSTC_rx				; set ostc_rx_present flag if this is an OSTC TR model

	; The hardware descriptor is now:
	; 0x11: 2 with BLE
	; 0x12; Sport
	; 0x13: +/2 with BLE & ambient			; PLUS ??? OSTC 3 (2016) ???
	; 0x05: cR
	; 0x0A: 3
	; 0x1A: 3 with BLE
	; 0x33: 2 TR

	btfss	ostc_rx_present					; OSTC TR detected?
	bra		restart5						; NO
	movff	opt_TR_mode,WREG				; YES - get user-selected TR mode
	tstfsz	WREG							;       TR functions switched on?
	bsf		FLAG_tr_enabled					;       YES - switch on displays and calculation functions
 ENDIF

	; configure hardware descriptor 2
	; flag  screen_type                  will be configured on each call of TFT_boot
	; flags compass_type & compass_type2 will be configured on each call of I2C_init_compass
	; flag  analog_switches              will be configured directly after hard start (in start:)

restart5:
	; Select high altitude (fly) mode?
	movff	last_surfpressure_30min+0,sub_b+0
	movff	last_surfpressure_30min+1,sub_b+1
	movlw	HIGH high_altitude_threshold
	movwf	sub_a+1
	movlw	LOW  high_altitude_threshold	; hard-wired 880 hPa
	movwf	sub_a+0
	call	subU16							; sub_c = sub_a - sub_b
	btfss	neg_flag						; result negative (ambient > 880 hPa)?
	bsf		high_altitude_mode				; NO - set flag

	btfss	analog_o2_input
	bsf		TRISB,3
	btfss	battery_gauge_available
	bsf		TRISG,0
	call	ext_flash_disable_protection	; disable write protection for external flash

	bsf		flip_screen						; select screen flip 180°
	TSTOSS	opt_flip_screen					; shall actually flip? (=1: flip the screen)
	bcf		flip_screen						; NO - revert to normal orientation

	btfsc	use_old_batt_flag				; =1: load old battery information after power-on reset
	goto	use_old_batteries				; returns to surface loop

	btfsc	RCON,POR						; was this a power-on reset?
	goto	surfloop						; NO - jump to surface loop
	bsf		RCON,POR						; set bit for next detection
	; Things to do after a power-on reset
	goto	do_new_battery_select			; returns to surface loop

;=============================================================================
; Setup all flags and parameters for divemode and simulator computations.
;
	global	restart_set_modes_and_flags
restart_set_modes_and_flags:				; "Call"ed from dive mode as well
	call	option_restore_all				; restore everything from EEPROM

	; Setup sampling rate
	movlw	.2
	movwf	samplingrate
	TSTOSS	opt_sampling_rate				; =1: 10s, =0: 2s
	bra		restart_set_modes_and_flags1
	movlw	.10
	movwf	samplingrate

restart_set_modes_and_flags1:
	bcf		FLAG_gauge_mode
	bcf		FLAG_apnoe_mode
	bcf		FLAG_oc_mode
	bcf		FLAG_ccr_mode
	bcf		FLAG_pscr_mode
	bcf		FLAG_bailout_mode
	call	disable_ir_s8					; IR off

 IFDEF _cave_mode
	bsf		FLAG_cave_mode					; enable cave mode by default
	movff	opt_calc_asc_gasvolume,WREG		; get gas needs calculation mode (0=off, 1=on, 2=cave mode)
	xorlw	.2								; coding for cave mode
	tstfsz	WREG							; cave mode enabled?
	bcf		FLAG_cave_mode					; NO - disable cave mode again
	bcf		FLAG_cave_mode_shutdown			; clear flag for cave mode shutdown
	bcf		FLAG_dive_turned				; clear flag for dive turned
	bcf		gas_needs_mode_last				; set last gas calculation results as direct ascent needs
 ENDIF

	; Initialize active_gas and active_dil for surface mode pressure display
	call	get_first_gas_to_WREG
	movwf	active_gas
	call	get_first_dil_to_WREG
	movwf	active_dil

	; Setup char_I_saturation_multiplier and char_I_desaturation_multiplier
	movff	opt_sat_multiplier_gf,char_I_saturation_multiplier
	movff	opt_desat_multiplier_gf,char_I_desaturation_multiplier
	movff	char_I_deco_model,lo			; 0 = ZH-L16, 1 = ZH-L16-GF
	tstfsz	lo
	bra		restart_set_modes_and_flags1b
	movff	opt_sat_multiplier_non_gf,char_I_saturation_multiplier
	movff	opt_desat_multiplier_non_gf,char_I_desaturation_multiplier

restart_set_modes_and_flags1b:
	movff	opt_dive_mode,lo				; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR
	tstfsz	lo
	bra		restart_set_modes_and_flags2

	; OC Mode
	bsf		FLAG_oc_mode					; =1: OC mode active
 IFDEF _rx_functions
	call	option_cleanup_oTrMode_no_CCR	; revert TR mode from 'CCR Dil+O2' to 'on'
 ENDIF
	return

restart_set_modes_and_flags2:
	decfsz	lo,F
	bra		restart_set_modes_and_flags3

	; CCR Mode
	bsf		FLAG_ccr_mode					; =1: CCR mode (Fixed SP, Auto SP or Sensor) active
	call	option_cleanup_oCCRMode_CCR		; revert CCR mode 'Sensor' to 'fixed SP' if no sensor interface available
 IFDEF _rx_functions
	call	option_cleanup_oTrMode_CCR		; revert TR mode from 'ind.double' to 'on'
 ENDIF
	call	enable_ir_s8					; enable IR/S8 port
	return

restart_set_modes_and_flags3:
	decfsz	lo,F
	bra		restart_set_modes_and_flags4

	; Gauge Mode
	bsf		FLAG_gauge_mode					; =1: in gauge mode
 IFDEF _rx_functions
	call	option_cleanup_oTrMode_no_CCR	; revert TR mode from 'CCR Dil+O2' to 'on'
 ENDIF
	return

restart_set_modes_and_flags4:
	decfsz	lo,F
	bra		restart_set_modes_and_flags5

	; Apnea Mode
	bsf		FLAG_apnoe_mode					; =1: in Apnea mode
 IFDEF _rx_functions
	call	option_cleanup_oTrMode_no_CCR	; revert TR mode from 'CCR Dil+O2' to 'on'
 ENDIF
	return									; start in surface mode

restart_set_modes_and_flags5:
	; pSCR Mode
	bsf		FLAG_pscr_mode					; set pSCR mode flag
	call	option_cleanup_oCCRMode_pSCR	; in pSCR mode, revert AutoSP (2) to calculated SP (0), additionally revert Sensor to fixed SP if no sensor interface available
 IFDEF _rx_functions
	call	option_cleanup_oTrMode_no_CCR	; revert TR mode from 'CCR Dil+O2' to 'on'
 ENDIF
	call	enable_ir_s8					; enable IR/S8 port
	return									; start in surface mode


; backup the first 128 bytes from flash to EEPROM
backup_flash_page:
	; Start address in internal flash
	movlw	0x00
	movwf	TBLPTRL
	movwf	TBLPTRH
	movwf	TBLPTRU

	movlw	.128
	movwf	lo								; byte counter
	clrf	EEADR
	movlw	.3
	movwf	EEADRH							; setup backup address

	TBLRD*-									; dummy read to be in 128 byte block
backup_flash_loop:
	tblrd+*									; table read with pre-increment
	movff	TABLAT,EEDATA					; put 1 byte
	call	write_eeprom					; save it in EEPROM
	incf	EEADR,F
	decfsz	lo,F							; 128 byte done?
	bra		backup_flash_loop				; NO - loop
	clrf	EEADRH							; reset EEADRH
	return									; done

	END