Mercurial > public > hwos_code
diff src/start.asm @ 623:c40025d8e750
3.03 beta released
author | heinrichsweikamp |
---|---|
date | Mon, 03 Jun 2019 14:01:48 +0200 |
parents | b87f23fae743 |
children | cd58f7fc86db |
line wrap: on
line diff
--- a/src/start.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/start.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File start.asm REFACTORED VERSION V2.99g +; File start.asm combined next generation V3.03.2 ; ; Startup subroutines ; @@ -11,7 +11,6 @@ #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" @@ -20,14 +19,17 @@ #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" +#include "divemode.inc" +#include "rx_ops.inc" + extern init_ostc extern option_restore_all + extern backup_flash_page extern restore_decodata_from_eeprom extern oPressureAdjust extern option_reset @@ -35,50 +37,63 @@ extern option_save_all extern option_check_all extern do_new_battery_select - extern use_old_batteries + extern get_battery_data extern use_old_prior_209 extern get_first_gas_to_WREG - extern get_first_dil_to_WREG + + IFDEF _ccr_pscr extern option_cleanup_oCCRMode_pSCR extern option_cleanup_oCCRMode_CCR + extern get_first_dil_to_WREG + ENDIF IFDEF _rx_functions extern option_cleanup_oTrMode_CCR extern option_cleanup_oTrMode_no_CCR + extern rx_firmware_new_major + extern rx_firmware_new_minor ENDIF +;----------------------------------------------------------------------------- + ;============================================================================= ; Reset Vector: entry point on device wake-up and hard reset ; -reset_v code 0x00000 +reset_v CODE 0x00000 + goto 0x1FF00 ; jump to bootloader -; goto start - goto 0x1FF00 ; bootloader - - ORG 0x00004 ; needed for second-level bootloader +start_v CODE 0x00004 ; jump to application (cold-)start goto start ;============================================================================= -boot CODE +boot CODE ;============================================================================= - +; Entry point after cold start +; 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 + ; clear RAM banks 0-14 + lfsr FSR0,0x000 ; load start address into FSR0 + movlw 0x0F ; load end address into WREG (actually its high byte) +start_clear_rambank: + clrf POSTINC0 ; clear memory location and increment FSR0 + cpfseq FSR0H ; has FSR0 reached begin of bank 15, i.e. banks 0-14 done? + bra start_clear_rambank ; NO - loop - call init_ostc ; initialize hardware (ports, timers, etc.) + ; initialize hardware (ports, timers, interrupts, etc.) + call init_ostc ; also selects bank common and sets CPU to normal speed + + ; flag that later restart origins from a cold start + bsf cold_start - ; get button type from Bootloader-Info - movlw .16 - movff WREG,analog_counter ; initialize averaging + ; initialize averaging for analog buttons + movlw .16 ; set averaging span + movff WREG,analog_counter ; write to counter + + ; get button type from bootloader info bsf analog_switches movlw 0x7C movwf TBLPTRL @@ -86,21 +101,21 @@ movwf TBLPTRH movlw 0x01 movwf TBLPTRU - TBLRD*+ ; reads 0x07 for analog buttons - movlw 0x07 - cpfseq TABLAT - bcf analog_switches + TBLRD*+ ; read configuration byte + movlw 0x07 ; coding for analog buttons + cpfseq TABLAT ; equal? + bcf analog_switches ; NO - no analog buttons - ; get screen type (2) from Bootloader-Info - bsf screen_type2 + ; 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 + movwf TBLPTRL ; only low byte adjustment needed, high and upper are still at 0x01F7xx + TBLRD*+ ; read configuration byte + movlw 0x83 ; coding for screen type 2 + cpfseq TABLAT ; equal? + bcf screen_type2 ; NO - not screen type 2 - ; read button polarity + ; get button polarity from configuration data (EEPROM) movlw LOW .897 movwf EEADR movlw HIGH .897 @@ -109,257 +124,223 @@ 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 + ; initialize pressure sensor calibration 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 + + ; wait for calibration data to take effect + bsf LEDr ; turn on red LED - clrf rel_pressure+0 - clrf rel_pressure+1 - clrf surface_interval+0 - clrf surface_interval+1 + ; first pass, will not have valid temperature yet + bcf trigger_pres_update ; make sure ISR pressure update confirmation is not older than from now on + btfss trigger_pres_update ; has the ISR confirmed a pressure update? + bra $-2 ; NO - not yet, loop waiting for the ISR to kick in - SAFE_2BYTE_COPY amb_pressure, last_surfpressure + ; second pass - complete sensor initialization + bcf trigger_pres_update ; make sure ISR pressure update confirmation is not older than from now on + btfss trigger_pres_update ; has the ISR confirmed a pressure update? + bra $-2 ; NO - not yet, loop waiting for the ISR to kick in - 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 + ; sensor calibration completed, first valid pressure value is available + bcf LEDr ; turn off red LED again -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 + ; load surface pressure into ISR + ; initially needs to be done twice in order to shift the current absolute pressure through the + ; 15 minutes sampling buffer into the reference buffer from where it is loaded by the ISR + rcall sample_surface_pressure ; 1st pass + rcall sample_surface_pressure ; 2nd pass + btfsc update_surface_pressure ; has the ISR confirmed loading of the surface pressure? + bra $-2 ; NO - not yet, loop until ISR has confirmed loading - 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 + ; reset all tissue pressures to surface pressure equilibrium state by default + call deco_clear_tissue ; (C-code) + banksel common - 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 - + ; restore tissue pressures from EEPROM (if available) movlw HIGH .512 ; =2 - movwf EEADRH + movwf EEADRH ; set EEPROM address, high byte 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 + movlw 0xAA ; coding for tissue pressures available + cpfseq EEDATA ; tissue pressures available? + bra start_1 ; NO - no tissue pressures available + call restore_decodata_from_eeprom ; YES - reload tissue pressures from EEPROM - bcf menubit ; clear menu flag - - ; check for power-on reset here +start_1: + bsf reset_surface_interval ; request ISR to reset the surface interval timer - ; ***************************************************************************** - ; "do_new_battery_menu" and "use_old_batteries" 'goto' back to "power_on_return" - ; ***************************************************************************** +; call rtc_init ; initialize the real time clock (will reset to firmware creation date) - ; Try to migrate the old battery status from firmware 2.09 or earlier.. + ; check for power-on reset btfsc RCON,POR ; was this a power-on reset? - call use_old_prior_209 ; NO + call use_old_prior_209 ; NO - migrate the last battery status from firmware 2.09 or earlier - bcf use_old_batt_flag + bcf use_old_batt_flag ; default to no reload of last battery data btfsc RCON,POR ; was this a power-on reset? - bsf use_old_batt_flag ; NO - + bsf use_old_batt_flag ; NO - reload last battery data + 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) + bra start_check_new_firmware ; NO - skip next + movlw .30 ; YES - load default button sensitivity + movff WREG,opt_cR_button_right ; - set default for left button + movff WREG,opt_cR_button_left ; - set default for right button + call piezo_config ; - configure buttons, 1st pass + call piezo_config ; - configure buttons, 2nd pass -check_firmware_new: - call TFT_boot ; initialize TFT (includes clear screen) - clrf CCPR1L ; backlight off +start_check_new_firmware: + call TFT_boot ; initialize TFT (includes clear screen & backlight switch-off) + ; show heinrichsweikamp logo 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 + TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block - 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 + ; check if a new firmware was loaded, if yes reset option oPressureAdjust + movlw d'1' ; set EEPROM address to 0x101 + movwf EEADR ; = 0x001 + movwf EEADRH ; = 0x101 + call read_eeprom ; read current version, major + movff EEDATA,lo ; store major in lo + incf EEADR,F ; set EEPROM address to 0x102 + call read_eeprom ; read current version, minor + movff EEDATA,hi ; store minor in 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_x ; get current major version + cpfseq lo ; compare with stored version, equal? + bra start_check_new_firmware_new ; NO - reset some options 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 + movlw softwareversion_y ; get current minor version + cpfseq hi ; compare with stored version, equal? + bra start_check_new_firmware_new ; NO - reset some options and store new version in EEPROM + bra start_check_new_firmware_old ; YES - both equal, do not reset options -check_firmware_new4: +start_check_new_firmware_new: + ; new firmware version detected + call show_fw_mesg_update ; show firmware update message + ; place "after-update reset" here... - lfsr FSR0,oPressureAdjust + lfsr FSR0,oPressureAdjust ; memory address of option data 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 + lfsr FSR0,oPressureAdjust ; memory address of option data + call option_save ; save reseted value of oPressureAdjust in 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 + ; store current version in EEPROM + movlw d'1' ; set EEPROM address to 0x101 + movwf EEADR ; = 0x001 + movwf EEADRH ; = 0x101 + movlw softwareversion_x ; get version, major number + movwf EEDATA ; prepare write + call write_eeprom ; execute write + incf EEADR,F ; set EEPROM address to 0x102 + movlw softwareversion_y ; get version, minor number + movwf EEDATA ; prepare write + call write_eeprom ; execute write clrf EEADRH ; reset EEADRH + bra start_check_new_firmware_common ; - ; 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 +start_check_new_firmware_old: + call show_fw_mesg_kept ; show firmware is kept message + +start_check_new_firmware_common: + call TFT_Display_FadeIn ; display resulting screen + call backup_flash_page ; back-up the first 128 bytes from program flash memory to EEPROM + + ; pause 5 seconds + movlw .5 ; load loop counter +start_check_new_firmware_wait: + call wait_1s ; wait <= 1 second + decfsz WREG,W ; decrement loop counter, did it became zero? + bra start_check_new_firmware_wait ; NO - loop + ;bra restart ; YES - proceed with restart +;============================================================================= +; Entry point after warm start +; +; called on leaving sleep mode, surface menu, communication mode, and +; when a start of a dive is detected in all modes except surface mode. +; global restart restart: - clrf STKPTR ; never return from here + banksel common ; for safety purpose only + clrf STKPTR ; clear return addresses stack clrf CCP1CON ; stop PWM bcf PORTC,2 ; pull PWM out to GND - btfsc menubit ; return from Menu/COMM mode or timeout? + call request_speed_normal ; request CPU speed change to normal speed (for safety only) + + ; manage the option settings + btfsc surfmode_menu ; was restart entered by return from surface menu or comm mode? 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 + btfss surfmode_menu ; was restart entered by return from surface menu or comm mode? + call option_restore_all ; NO - load all settings from EEPROM + + call option_check_all ; check all options and repair them if not within their min/max boundaries + + btfsc option_repaired ; errors found & repaired during options check? + call option_save_all ; YES - save corrected settings into EEPROM + + ; clear flag groups + clrf HW_descriptor ; hardware - OSTC model descriptor + clrf HW_flags_state ; hardware - status + clrf DM_flags_sensor ; hardware - O2 sensors + + clrf OS_flags_ISR1 ; operating system - ISR control 1 + clrf OS_flags_ISR2 ; operating system - ISR control 2 - 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 eventbase ; event triggers generated by ISR + + clrf DM_flags_deco ; dive deco modes + + clrf MS_flags_control ; menu system - control + clrf MS_flags_imprint ; menu system - data imprinting - 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! + clrf CVT_flags1 ; convert and display functions + clrf CVT_flags2 ; convert and display functions - bsf tft_is_dimming ; TFT is dimming up (soon), ignore ambient sensor! + ; TFT will be dimming soon, ignore ambient sensor + bsf tft_is_dimming - ; configure hardware descriptor 1 + ; configure the OSTC model descriptor (stored in HW_descriptor) 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 + bsf ambient_sensor ; set ambient light sensor as available by default + bsf optical_input ; set optical input as available by default call lt2942_get_status ; check for gauge IC - btfss battery_gauge_available ; cR/2 hardware? + btfss battery_gauge_available ; OSTC 2, cR or TR? bra restart2 ; NO - call lt2942_init ; YES - initialize battery gauge IC - bcf optical_input ; clear flag - banksel 0xF16 + ; OSTC 2, cR or TR + call lt2942_init ; initialize battery gauge IC + bcf optical_input ; OSTC 2, cR and TR do not have an optical input + + banksel ANCON0 ; ANCON0 is outside access RAM bcf ANCON0,7 ; AN7 digital input - banksel common + banksel common ; back to bank common bcf lightsen_power ; power-down ambient light sensor - bcf ambient_sensor ; clear flag + bcf ambient_sensor ; no ambient light sensor by default nop - btfss PORTF,2 ; light sensor available? + btfss PORTF,2 ; ambient light sensor available? bsf ambient_sensor ; YES - banksel 0xF16 + banksel ANCON0 ; ANCON0 is outside access RAM bsf ANCON0,7 ; AN7 analog again - banksel common + banksel common ; back to bank 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 + btfsc vusb_in ; USB power detected? + bra restart3 ; YES + bcf PORTE,0 ; start comm + WAITMS d'5' ; wait 5 ms + btfss vusb_in ; USB power detected? + bra restart3 ; NO + bsf ble_available ; YES - BLE available restart3: - bsf PORTE,0 ; stop comms + bsf PORTE,0 ; stop comm btfsc ble_available ; BLE available? bra restart4 ; YES - can't be a cR btfss battery_gauge_available ; rechargeable? @@ -367,193 +348,271 @@ bsf analog_o2_input ; set flag for analog restart4: + bsf lv_core ; default to low voltage core + movlw 0x80 ; point to 0x1F780 + movwf TBLPTRL + movlw 0xF7 + movwf TBLPTRH + movlw 0x01 + movwf TBLPTRU + TBLRD*+ ; read from 0x1F780 + movlw 0x83 ; coding for low voltage core, part 1 + cpfseq TABLAT ; equal? + bra restart4a ; NO - no low voltage core then + movlw 0x81 ; point to 0x1F781 + movwf TBLPTRL + TBLRD*+ ; read from 0x1F781 + movlw 0x94 ; coding for low voltage core, part 2 + cpfseq TABLAT ; equal? +restart4a: + bcf lv_core ; NO - no low voltage core then + + IFDEF _rx_functions - WAITMS d'200' - call I2C_probe_OSTC_rx ; set ostc_rx_present flag if this is an OSTC TR model + + ; set TR functions as deactivated by default + bcf tr_functions_activated ; clear flag + + ; search for TR module + WAITMS .200 ; wait 200 ms while RX module boots up + call I2C_probe_OSTC_rx ; check for RX module and set ostc_rx_present flag if found + btfss ostc_rx_present ; RX module detected? + bra restart5 ; NO + + ; check if TR module firmware is up to date + movff rx_firmware_cur_major,hi ; copy current firmware on RX module to bank common, major + movff rx_firmware_cur_minor,lo ; copy current firmware on RX module to bank common, minor + call rx_firmware_new_major ; get latest firmware version into WREG, major + cpfseq hi ; equal to current firmware on RX module, major ? + bra restart4b ; NO - update + call rx_firmware_new_minor ; YES - get latest firmware version into WREG, minor + cpfseq lo ; - equal to current firmware on RX module, minor ? + bra restart4b ; NO - update TR module + bra restart4e ; YES - no need to update - ; 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 +restart4b: + ; print TR module update message + call TFT_boot ; initialize TFT (includes clear screen & backlight switch-off) + WIN_TOP .40 ; show heinrichsweikamp logo + WIN_LEFT .10 + TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block + WIN_SMALL .10,.130 + STRCAT_PRINT "Updating TR Module..." ; print update message + call TFT_Display_FadeIn ; display screen + WIN_SMALL .10,.160 + STRCAT "TR Update " ; prepare result message + + ; update firmware in RX module + call I2C_sleep_accelerometer ; stop accelerometer + call I2C_sleep_compass ; stop compass + call update_tr_module ; update TR module - btfss ostc_rx_present ; OSTC TR detected? + WIN_SMALL .10,.160 ; set next output position + STRCAT "Update " ; common part of result message + btfss ostc_rx_present ; data transfer successful and TR module up & running again? + bra restart4c ; NO + STRCAT "to " ; YES - print success message + call TFT_print_firmware_rx ; - print installed version + STRCAT_PRINT " done" ; - complete result message + bra restart4d ; - show message for a while + +restart4c: + STRCAT_PRINT "failed" ; complete result message - failure + +restart4d: + call wait_1s ; wait (up to) 1 second + call wait_1s ; wait (another full) 1 second + call wait_1s ; wait (another full) 1 second + +restart4e: + btfss ostc_rx_present ; TR module up & running? 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 + movff opt_TR_mode,WREG ; YES - get TR mode + tstfsz WREG ; - TR mode <> off ? + bsf tr_functions_activated ; YES - set TR functions as activated - ; 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:) + ENDIF ; _rx_functions + 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 + ; manage hardware + btfss analog_o2_input ; OSTC with analog input? + bsf TRISB,3 ; NO - shut down power supply for S8 bulkhead - btfss analog_o2_input - bsf TRISB,3 - btfss battery_gauge_available - bsf TRISG,0 + btfss battery_gauge_available ; OSTC with gauge IC? + bsf TRISG,0 ; NO + 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 ; shall reload last battery data? + call get_battery_data ; YES - get last battery data + + ; set screen orientation + bcf flip_screen ; set default screen orientation + TSTOSC opt_flip_screen ; shall show screen outputs upside down? (=1: flip the screen) + bsf flip_screen ; YES - set upside-down orientation - btfsc use_old_batt_flag ; =1: load old battery information after power-on reset - goto use_old_batteries ; returns to surface loop + ; check if high-altitude mode is applicable + bcf high_altitude_mode ; disable high altitude mode by default + MOVII pressure_abs_ref, sub_a ; copy last surface pressure to sub_a + MOVLI high_altitude_threshold+1,sub_b ; copy high-altitude threshold (880 mbar) + 1 to sub_a + call cmpU16 ; sub_a - sub_b = pressure_abs_ref - (high_altitude_threshold + 1) + btfsc neg_flag ; result negative (absolute pressure <= 880 mbar) ? + bsf high_altitude_mode ; YES - enable high altitude mode + + ; check if there was a cold start, if yes do initial computation of further deco data + btfss cold_start ; did a cold start? + bra restart6 ; NO + bcf cold_start ; YES - clear flag + call deco_calc_dive_interval_1min ; - calculate tissues for 1 minute at surface conditions (C-code) + call deco_calc_desaturation_time ; - calculate desaturation and no-fly/no-altitude time (C-code) + banksel common ; - back to bank common + +restart6: + ; the dive mode flag can not be set right after cold start, must have been in surface mode before + btfsc divemode ; shall enter dive mode? + goto diveloop ; YES 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 + goto surfloop ; NO - enter surface mode + bsf RCON,POR ; YES - acknowledge detection and re-arm detector + goto do_new_battery_select ; - prompt for battery selection, will proceed to surface mode + ;============================================================================= -; Setup all flags and parameters for divemode and simulator computations. +; Setup all flags and parameters for dive mode and simulator computations +; +; called from divemode.asm, menu_tree.asm and surfmode.asm ; 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 +restart_set_modes_and_flags: + call option_restore_all ; restore all options settings from EEPROM + + IFDEF _external_sensor + call disable_ir_s8 ; switch off IR/S8 digital interface by default + ENDIF - ; 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 + ; setup sampling rate + movlw .2 ; default to 2 seconds + movwf sampling_rate ; write setting + TSTOSS opt_sampling_rate ; check option: 1= 10s, 0= 2s + bra restart_set_modes_and_flags1 ; 0 - 2 seconds selected, done + movlw .10 ; 1 - change to 10 seconds + movwf sampling_rate ; - write setting 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 + clrf DM_flags_deco ; clear all deco mode flags - 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 + ; initialize active_gas and active_dil for surface mode pressure display call get_first_gas_to_WREG movwf active_gas + + IFDEF _ccr_pscr 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 + ENDIF -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 + ; configure saturation / desaturation safety factors + movff opt_sat_multiplier_gf, char_I_saturation_multiplier ; use factors for GF mode by default + movff opt_desat_multiplier_gf,char_I_desaturation_multiplier ; ... + TSTOSC char_I_deco_model ; get deco model ZH-L16-GF (1) selected? + bra restart_set_modes_and_flags2 ; YES - keep them + movff opt_sat_multiplier_non_gf, char_I_saturation_multiplier ; NO - overwrite them with non-GF factors + movff opt_desat_multiplier_non_gf,char_I_desaturation_multiplier ; - ... restart_set_modes_and_flags2: - decfsz lo,F - bra restart_set_modes_and_flags3 + ; configure GF settings, GF high is needed for color-coding the current GF (supersaturation) factor + movff opt_GF_low, char_I_GF_Low_percentage + movff opt_GF_high,char_I_GF_High_percentage - ; 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 + movff opt_dive_mode,lo ; get dive mode: 0= OC, 1= CCR, 2= gauge, 3= apnea, 4= pSCR + tstfsz lo ; OC? + bra restart_set_modes_and_flags3 ; NO + bsf FLAG_oc_mode ; YES - set OC flag IFDEF _rx_functions - call option_cleanup_oTrMode_CCR ; revert TR mode from 'ind.double' to 'on' + 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 + return ; - done restart_set_modes_and_flags3: - decfsz lo,F - bra restart_set_modes_and_flags4 - - ; Gauge Mode - bsf FLAG_gauge_mode ; =1: in gauge mode + decfsz lo,F ; CCR mode? + bra restart_set_modes_and_flags4 ; NO + IFDEF _ccr_pscr + bsf FLAG_ccr_mode ; YES - set CCR flag + call option_cleanup_oCCRMode_CCR ; - revert CCR mode '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 - return + call option_cleanup_oTrMode_CCR ; - revert TR mode from 'ind.double' to 'on' + ENDIF ; _rx_functions + IFDEF _external_sensor + call enable_ir_s8 ; - enable IR/S8 digital interface + ENDIF ; _external_sensor + ENDIF ; _ccr_pscr + return ; - done restart_set_modes_and_flags4: - decfsz lo,F - bra restart_set_modes_and_flags5 - - ; Apnea Mode - bsf FLAG_apnoe_mode ; =1: in Apnea mode + decfsz lo,F ; Gauge mode? + bra restart_set_modes_and_flags5 ; NO + bsf FLAG_gauge_mode ; YES - set gauge flag IFDEF _rx_functions - call option_cleanup_oTrMode_no_CCR ; revert TR mode from 'CCR Dil+O2' to 'on' + call option_cleanup_oTrMode_no_CCR ; - revert TR mode from 'CCR Dil+O2' to 'on' ENDIF - return ; start in surface mode + return ; - done 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 + decfsz lo,F ; Apnea mode? + bra restart_set_modes_and_flags6 ; NO + bsf FLAG_apnoe_mode ; YES - set apnea flag + movlw samplingrate_apnoe ; get apnoe sampling rate + movwf sampling_rate ; overwrite user-selected 2/10 seconds setting with apnoe default IFDEF _rx_functions - call option_cleanup_oTrMode_no_CCR ; revert TR mode from 'CCR Dil+O2' to 'on' + 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 + return ; - done + +restart_set_modes_and_flags6: + ; pSCR mode then + IFDEF _ccr_pscr + bsf FLAG_pscr_mode ; - set pSCR mode flag + call option_cleanup_oCCRMode_pSCR ; - revert AutoSP to calculated SP, 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 ; _rx_functions + IFDEF _external_sensor + call enable_ir_s8 ; - enable IR/S8 digital interface + ENDIF ; _external_sensor + ENDIF ; _ccr_pscr + return ; - done -; 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 +;============================================================================= +; Sample and store the current surface pressure, update ISR and deco engine +; with the surface pressure sampled on last invocation. +; + global sample_surface_pressure +sample_surface_pressure: + ; make sure the ISR does not read the surface pressure reference buffer while it is updated + bcf update_surface_pressure ; cancel any pending load request + + ; propagate the surface pressure sampled on last invocation to the reference pressure buffer + MOVII pressure_abs_sampled,pressure_abs_ref + + ; update surface pressure in the ISR + bsf update_surface_pressure ; request ISR to update its surface pressure - movlw .128 - movwf lo ; byte counter - clrf EEADR - movlw .3 - movwf EEADRH ; setup backup address + ; update surface pressure in the deco engine + MOVII pressure_abs_ref,int_I_pres_surface + + ; sample current absolute pressure (ISR-safe 2 byte copy) + SMOVII pressure_abs,pressure_abs_sampled - 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 + ; limit sampled pressure to max allowed surface pressure + MOVLI max_surfpressure, sub_a ; load upper limit into sub_a + MOVII pressure_abs_sampled,sub_b ; copy sampled pressure to sub_b + call cmpU16 ; sub_a - sub_b = max_surfpressure - pressure_abs_sampled + btfss neg_flag ; sampled pressure > max_surfpressure ? + return ; NO - below limit, done + MOVII sub_a,pressure_abs_sampled ; YES - limit to max_surfpressure (still stored in sub_a) + return ; - done + END \ No newline at end of file