view src/start.asm @ 572:0039f057b90f

Fix time of dive in internal logbook
author heinrichsweikamp
date Mon, 12 Feb 2018 16:24:58 +0100
parents 8b7ea27ea1fa
children b455b31ce022
line wrap: on
line source

;=============================================================================
;
;   File start.asm									REFACTORED VERSION	V2.95a1
;
;   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

;=============================================================================
; Reset vector: What to do 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 rambank 0-14
clear_rambank:
	clrf	POSTINC0
	movlw	0x0F
	cpfseq	FSR0H					; Bank 14 done?
	bra		clear_rambank			; clear...

    call    init_ostc

    ; Get button type from Bootloader-Info
	movlw   .16
	movff   WREG,analog_counter	; init 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

	; 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			; display off
	bsf     LEDr                    ; Status 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" airpressure in mbar
	movlw	HIGH	max_surfpressure
	movff	WREG,sub_a+1				; max. "allowed" airpressure 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 1080mbar < amb_pressure ?
	bra		start_copy_pressure			; NO: current airpressure is lower then "allowed" airpressure, ok!

    ; not ok! Overwrite with max. "allowed" airpressure
	movlw	LOW		max_surfpressure
	movff	WREG,last_surfpressure+0	; max. "allowed" airpressure in mbar
	movlw	HIGH	max_surfpressure
	movff	WREG,last_surfpressure+1	; max. "allowed" airpressure 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 airpressure registers

; reset deco data for surface mode
	movlw	.21												; 21%
	movff	WREG,char_I_O2_ratio            				; ... oxygen
	movlw	.0												;  0%
	movff	WREG,char_I_He_ratio            				; ... helium

	; 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 pressue
	movff	int_I_pres_respiration+1,int_I_pres_surface+1		

	extern	deco_setup
	call	deco_setup				; set up all model parameters.
    call    deco_clear_tissue       ; Set all tissues to Pamb * N2_ratio (C-Code)
    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

    extern  restore_decodata_from_eeprom
    call    restore_decodata_from_eeprom    ; Reload deco data and date/time from eeprom

no_deco_restore:
	call	deco_calc_wo_deco_step_1_min	; 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
	extern	use_old_prior_209
    ; *****************************************************************************
	; "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	    power_on_return2		    	; no

    movlw   .30
    movff   WREG,opt_cR_button_right
    movff   WREG,opt_cR_button_left         ; Reset on power-on reset
    call    piezo_config                    ; Yes, configure buttons
    call    piezo_config                    ; Yes, configure buttons (2 times)

power_on_return2:
; check firmware and reset Custom Functions after an update
	movlw	d'1'
	movwf	EEADR                   ; =1
	movwf	EEADRH                  ; =1
	call	read_eeprom				; read current version x
	movff	EEDATA,temp1
	incf	EEADR,F					; set to 0x102
	call	read_eeprom				; read current version y
	movff	EEDATA,temp2
	clrf	EEADRH					; Reset EEADRH

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

	movlw	softwareversion_y
	cpfseq	temp2					; compare version y
	bra		check_firmware_new		; is not equal -> reset CF and store new version in EEPROM
	bra		restart					; x and y are equal -> do not reset cf
		
check_firmware_new:
	call	TFT_boot                ; Initialize TFT (includes clear screen)
	clrf    CCPR1L          		; Backlight off
    WIN_TOP     .50
    WIN_LEFT    .10
    movlw   LOW     0x1E000
    movwf   TBLPTRL
    movlw   HIGH    0x1E000
    movwf   TBLPTRH
    movlw   UPPER   0x1E000
    movwf   TBLPTRU
    extern  color_image
    call    color_image             ; Show logo
	call	TFT_standard_color
	WIN_SMALL   .10,.100
	STRCPY_PRINT	"Update successful!"		; Hard coded since language switch does not work here
	WIN_SMALL   .10,.140
	STRCPY		"New Firmware: "
	movlw	softwareversion_x
	movwf	lo
	bsf		leftbind
	output_8
	PUTC	"."
	movlw	softwareversion_y
	movwf	lo
	output_99x
	bcf		leftbind
	STRCAT_PRINT	""				; Print second row
    call    TFT_Display_FadeIn      ; Display resulting surface screen.

; place "after-update reset" here...

    extern  oPressureAdjust, option_reset, option_save
    lfsr    FSR0,oPressureAdjust
    call    option_reset            ; Reset FSR0 option to factory default.
    lfsr    FSR0,oPressureAdjust
    call    option_save             ; Save in EEPROM

    rcall   backup_flash_page       ; backup the first 128bytes 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 x
	incf	EEADR,F					; set to 0x102
	movlw	softwareversion_y
	movwf	EEDATA		
	call	write_eeprom			; write version y
	clrf	EEADRH					; Reset EEADRH

	movlw	.7
	movwf	lo
check_firmware_new2:
	; Wait 1 second
	bcf		onesecupdate
	btfss	onesecupdate
	bra		$-2
	decfsz	lo,F					; Wait 10 seconds...
	bra		check_firmware_new2

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

	extern	option_save_all, option_check_all

	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
    ; Do not clear flag11 (Sensor calibration and charger status)
    clrf	flag12
    ; Do not clear flag13 (Important hardware flags)
    clrf	flag14
    clrf	hardware_flag           ; hardware descriptor flag
    bsf		tft_is_dimming          ; TFT is dimming up (soon), ignore ambient sensor!

    ; configure hardware_flag byte

    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, init 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'1'
    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:
    ; The hardware_flag is now:
    ; 3: 0x0A
    ; cR: 0x05
    ; 2 with BLE: 0x11
    ; 3 with BLE: 0x1A 
    ; 2 with ambient: 0x13

	; 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 880mbar
	movwf	sub_a+0
	call	subU16					; sub_c = sub_a - sub_b
	btfss	neg_flag				; Result negative (Ambient>880mbar)?
	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             ; Flip 180°
    TSTOSS  opt_flip_screen         ; =1: Flip the screen
    bcf     flip_screen             ; Normal orientation

    btfsc   use_old_batt_flag   	; =1: load old battery information after power-on reset
    goto    use_old_batteries		; Returns to "surfloop"!

    btfsc   RCON,POR	   			; Was this a power-on reset?
    goto    surfloop	    		; Jump to Surfaceloop!
    bsf	    RCON,POR	    		; Set bit for next detection
    ; Things to do after a power-on reset
    extern  new_battery_menu,use_old_batteries
    goto    new_battery_menu		; Returns to "surfloop"!

;=============================================================================
; Setup all flags and parameters for divemode and simulator computations.
;
	global	restart_set_modes_and_flags
restart_set_modes_and_flags:		    ; "Call"ed from divemode, 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	    twosecupdate				; to have divemode routines in sync
    
    bcf	    FLAG_apnoe_mode
    bcf     FLAG_ccr_mode				; =1: CCR mode (Fixed ppO2 or Sensor) active
    bcf     FLAG_gauge_mode				; =1: In Gauge mode
    bcf	    FLAG_pscr_mode
    call    disable_ir_s8				; IR off

    ; 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
	
    return

restart_set_modes_and_flags2:
    decfsz  lo,F
    bra     restart_set_modes_and_flags3
    ; CC Mode
    btfsc   analog_o2_input                 ; cR?
    bra     restart_set_modes_and_flags2b   ; Yes, skip mode check
    btfsc   optical_input                   ; 3
    bra     restart_set_modes_and_flags2b   ; Yes, skip mode check
    ; Make sure Sensor is not selected
    ; opt_ccr_mode must be <> 1 (=0: Fixed SP, =1: Sensor, =2: Auto SP)
    banksel opt_ccr_mode
    movlw   .1
    cpfseq  opt_ccr_mode                    ; = Sensor?
    bra     restart_set_modes_and_flags2b   ; No
    clrf    opt_ccr_mode                    ; Yes, reset to Fixed SP
restart_set_modes_and_flags2b:
    banksel common
	bsf     FLAG_ccr_mode               	; =1: CCR mode (Fixed SP, Auto SP or Sensor) active
    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
    return

restart_set_modes_and_flags4:
    decfsz  lo,F
    bra     restart_set_modes_and_flags5
    ; Apnea Mode
    bsf		FLAG_apnoe_mode
    return							    	; start in Surfacemode

restart_set_modes_and_flags5:
	; PSCR Mode
	btfsc	analog_o2_input					; cR?
	bra		restart_set_modes_and_flags5b	; Yes, skip mode check
	btfsc	optical_input					; 3
	bra		restart_set_modes_and_flags5b	; Yes, skip mode check

	; Make sure Sensor is not selected
	; opt_ccr_mode must be <> 1 (=0: calculated ppO2, =1: Sensor, =2: Auto SP - not valid in pSCR, too)
	banksel	opt_ccr_mode
	movlw	.1
	cpfseq	opt_ccr_mode					; = Sensor?
	bra		restart_set_modes_and_flags5b	; No
	clrf	opt_ccr_mode					; Yes, reset to calculated ppO2

restart_set_modes_and_flags5b:
	banksel	opt_ccr_mode
	bcf		opt_ccr_mode,1					; in pSCR mode only calculated or Sensor, not 2 = Auto SP allowed
	banksel	common
	bsf		FLAG_pscr_mode
	return									; start in Surfacemode

    
backup_flash_page:       ; backup the first 128bytes from flash to EEPROM
    	; 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            	; 128byte done?
        bra 	backup_flash_loop 	; No
        clrf    EEADRH          	; Reset EEADRH
        return                  	; Done.

	END