Mercurial > public > hwos_code
view src/ghostwriter.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 | ca4556fb60b9 |
children | c40025d8e750 |
line wrap: on
line source
;============================================================================= ; ; File ghostwriter.asm REFACTORED VERSION V2.99a ; ; Ghostwriter (Log profile recorder) ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= ; HISTORY ; 2011-11-27 : [mH] Creation #include "hwos.inc" ; Mandatory header #include "shared_definitions.h" ; Mailbox from/to p2_deco.c #include "external_flash.inc" #include "surfmode.inc" #include "eeprom_rs232.inc" #include "strings.inc" #include "isr.inc" #include "tft_outputs.inc" #include "divemode.inc" #include "rtc.inc" extern deco_pull_tissues_from_vault ;---- Private local variables ------------------------------------------------- CBLOCK local3 ; max size is 16 Byte !!! divisor_temperature ; divisor used to time the sampling of dive data divisor_deco ; divisor used to time the sampling of dive data divisor_gf ; divisor used to time the sampling of dive data divisor_ppo2_sensors ; divisor used to time the sampling of dive data divisor_decoplan ; divisor used to time the sampling of dive data divisor_cns ; divisor used to time the sampling of dive data divisor_tank ; divisor used to time the sampling of dive data ProfileFlagByte ; used to store events ENDC ; used: 8 byte, remaining: 8 byte ghostwriter CODE ;============================================================================= global init_recording_params ; initialize profile recording parameters init_recording_params: movff samplingrate,samplesecs_value; to avoid EEPROM access in the ISR movlw div_temperature movwf divisor_temperature ; load divisors for profile storage movlw div_deco movwf divisor_deco movlw div_gf movwf divisor_gf movlw div_ppo2_sensors movwf divisor_ppo2_sensors movlw div_decoplan movwf divisor_decoplan movlw div_cns movwf divisor_cns movlw div_tank movwf divisor_tank btfss FLAG_apnoe_mode ; in Apnoe mode? bra init_recording_params_1 ; NO movlw samplingrate_apnoe ; YES - overwrite some parameters in Apnoe mode movwf samplesecs_value ; to avoid EEPROM access in the ISR init_recording_params_1: btfsc FLAG_ccr_mode ; in CCR mode? bra init_recording_params_2 ; YES btfsc FLAG_pscr_mode ; in pSCR mode? bra init_recording_params_2 ; YES ; in all modes but CCR and pSCR, disable ppO2 logging movlw .0 movwf divisor_ppo2_sensors init_recording_params_2: return global store_dive_data store_dive_data: bcf store_sample ; clear flag ifndef __DEBUG btfsc simulatormode_active ; are we in simulator mode? return ; YES - discard everything endif btfsc FLAG_apnoe_mode ; in Apnoe mode? return ; YES - discard everything SAFE_2BYTE_COPY rel_pressure, lo movf lo,W ; store depth with every sample rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf hi,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash ; First, find out how many bytes will be appended to this sample set clrf ProfileFlagByte ; clear number of bytes to append ; Check Extended informations decfsz divisor_temperature,W ; check divisor bra check_extended1 movlw infolength_temperature addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended1: decfsz divisor_deco,W ; check divisor bra check_extended2 movlw infolength_deco addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended2: decfsz divisor_gf,W ; check divisor bra check_extended3 movlw infolength_gf addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended3: decfsz divisor_ppo2_sensors,W ; check divisor bra check_extended4 movlw infolength_ppo2_sensors addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended4: decfsz divisor_decoplan,W ; check divisor bra check_extended5 movlw infolength_decoplan addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended5: decfsz divisor_cns,W ; check divisor bra check_extended6 movlw infolength_cns addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended6: decfsz divisor_tank,W ; check divisor bra check_extended7 movlw infolength_tank addwf ProfileFlagByte,F ; add to ProfileFlagByte check_extended7: ; Second, check global event flag btfss event_occured ; check global event flag bra store_dive_data3 ; no event incf ProfileFlagByte,F ; add one byte (the EventByte1) clrf EventByte1 ; reset EventByte1 clrf EventByte2 ; reset EventByte2 movf AlarmType,W ; type of Alarm Bit 0-3 addwf EventByte1,F ; copy to EventByte1 Bit 0-3 clrf AlarmType ; reset AlarmType ; Third, check events and add additional bytes btfss gas6_changed ; check flag bra check_event2 movlw d'2' ; information length addwf ProfileFlagByte,F ; add to ProfileFlagByte bsf EventByte1,4 ; also set Flag in EventByte1! check_event2: btfss stored_gas_changed ; check flag bra check_event3 movlw d'1' ; information length addwf ProfileFlagByte,F ; add to ProfileFlagByte bsf EventByte1,5 ; also set Flag in EventByte1! check_event3: btfss setpoint_changed ; check flag bra check_event4 movlw d'1' ; information length addwf ProfileFlagByte,F ; add to ProfileFlagByte bsf EventByte1,6 ; also set Flag in EventByte1! check_event4: btfss bailoutgas_event ; =1: bailout was selected or a gas change during bailout bra check_event5 movlw d'2' ; information length addwf ProfileFlagByte,F ; add to ProfileFlagByte bsf EventByte2,0 ; set flag in EventByte2! bsf EventByte1,7 ; =1: another EventByte1 is available check_event5: ; more events? store_dive_data3: btfsc EventByte1,7 ; =1: Another EventByte1 is available incf ProfileFlagByte,F ; add one byte (The EventByte2) btfsc event_occured ; check global event flag bsf ProfileFlagByte,7 ; set EventByte1 flag in ProfileFlagByte movf ProfileFlagByte,W ; finally, write ProfileFlagByte rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash btfss event_occured ; check global event flag (again) bra store_dive_data4 ; no event ; Store the EventByte(s) + additional bytes now movf EventByte1,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf EventByte2,W ; write second event byte... btfsc EventByte1,7 ; =1: another EventByte1 is available rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash btfss gas6_changed ; check flag bra store_dive_data3b movff char_I_O2_ratio,WREG ; store gas 6 o2 ratio rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movff char_I_He_ratio,WREG ; store gas 6 He ratio rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash bcf gas6_changed ; clear this event store_dive_data3b: btfss stored_gas_changed ; check flag bra store_dive_data3c movf active_dil,W ; store active diluent (default, may be overwritten soon) btfsc FLAG_oc_mode ; in OC mode? movf active_gas,W ; YES - store active gas btfsc FLAG_bailout_mode ; in bailout? movf active_gas,W ; YES - store active OC = bailout gas rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash bcf stored_gas_changed ; clear this event store_dive_data3c: btfss setpoint_changed ; check flag bra store_dive_data3d movff char_I_const_ppO2,WREG ; store setpoint rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash bcf setpoint_changed ; clear this event store_dive_data3d: btfss bailoutgas_event ; check flag bra store_dive_data4 movff char_I_O2_ratio,WREG ; store O2 ratio of bailout gas rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movff char_I_He_ratio,WREG ; store He ratio of bailout gas rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash bcf bailoutgas_event ; clear this event store_dive_data4: ; Store extended information decfsz divisor_temperature,F ; check divisor bra store_extended1 rcall store_dive_temperature store_extended1: decfsz divisor_deco,F ; check divisor bra store_extended2 rcall store_dive_decodata store_extended2: decfsz divisor_gf,F ; check divisor bra store_extended3 rcall store_dive_gf store_extended3: decfsz divisor_ppo2_sensors,F ; check divisor bra store_extended4 rcall store_dive_ppO2_sensors store_extended4: decfsz divisor_decoplan,F ; check divisor bra store_extended5 rcall store_dive_decoplan store_extended5: decfsz divisor_cns,F ; check divisor bra store_extended6 rcall store_dive_cns store_extended6: decfsz divisor_tank,F ; check divisor bra store_extended7 rcall store_dive_tank store_extended7: ; The next block is required to take care of "store never" btfsc divisor_temperature,7 ; test highest bit (register must have been zero before the "decfsz" command!) clrf divisor_temperature ; and clear register again, so it will never reach zero... btfsc divisor_deco,7 clrf divisor_deco btfsc divisor_gf,7 clrf divisor_gf btfsc divisor_ppo2_sensors,7 clrf divisor_ppo2_sensors btfsc divisor_decoplan,7 clrf divisor_decoplan btfsc divisor_cns,7 clrf divisor_cns btfsc divisor_tank,7 clrf divisor_tank store_dive_data5: bcf event_occured ; clear the global event flag clrf EventByte1 ; reset EventByte1 clrf EventByte2 ; reset EventByte2 return ; done (sample with all informations written to external flash) store_dive_cns: movff int_O_CNS_fraction+0,WREG rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movff int_O_CNS_fraction+1,WREG bcf WREG,int_warning_flag ; clear warning flag bcf WREG,int_attention_flag ; clear attention flag rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_cns movwf divisor_cns ; reload divisor from CF return store_dive_tank: ; OSTC TR tank pressure logging movlw div_tank movwf divisor_tank ; reload divisor from CF return store_dive_decoplan: ; Store the deco plan lfsr FSR1,char_O_deco_time_for_log+.0 movlw .15 movwf lo store_dive_decoplan_loop: movf POSTINC1,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash decfsz lo,F bra store_dive_decoplan_loop movlw div_decoplan movwf divisor_decoplan ; reload divisor from CF return store_dive_ppO2_sensors: movf o2_ppo2_sensor1,W ; Sensor1 ppO2 (in 0.01 bar steps) rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash SAFE_2BYTE_COPY o2_mv_sensor1,lo ; o2_mv_sensor may be modified via ISR during the two writes here... movf lo,W ; in 0.1 mV steps rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf hi,W ; in 0.1 mV steps rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf o2_ppo2_sensor2,W ; Sensor2 ppO2 (in 0.01 bar steps) rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash SAFE_2BYTE_COPY o2_mv_sensor2,lo ; o2_mv_sensor may be modified via ISR during the two writes here... movf lo,W ; in 0.1 mV steps rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf hi,W ; in 0.1 mV steps rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf o2_ppo2_sensor3,W ; Sensor3 ppO2 (in 0.01 bar steps) rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash SAFE_2BYTE_COPY o2_mv_sensor3,lo ; o2_mv_sensor may be modified via ISR during the two writes here... movf lo,W ; in 0.1 mV steps rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf hi,W ; in 0.1 mV steps rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_ppo2_sensors movwf divisor_ppo2_sensors ; reload divisor return store_dive_gf: movff int_O_gradient_factor+0,WREG ; gradient factor absolute (range is limited to 255, only lower byte used for value) rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_gf movwf divisor_gf ; reload divisor return store_dive_decodata: ; Check if deco stops are necessary movff char_O_first_deco_depth,WREG ; get ceiling tstfsz WREG ; ceiling < 0 m (aka in deco) ? bra store_dive_decodata_deco ; YES ; NO - within NDL clrf WREG ; =0: no stop dive rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movff char_O_nullzeit,WREG ; remaining NDL time rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash bra store_dive_decodata_common store_dive_decodata_deco: ; YES - in deco movff char_O_first_deco_depth,WREG ; ceiling in m rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movff char_O_first_deco_time,WREG ; length of first stop in minutes rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash store_dive_decodata_common: movlw div_deco movwf divisor_deco ; Reload divisor return store_dive_temperature: SAFE_2BYTE_COPY temperature,lo movf lo,W ; append temperature to current sample! rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf hi,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_temperature movwf divisor_temperature ; reload divisor return ghostwrite_byte_header: goto write_byte_ext_flash_plus_header ; (this call will also delete the 4kB TOC entry first) ; returns... ghostwrite_byte_profile: goto write_byte_ext_flash_plus ; writes byte and increases address with banking at 0x200000 ; returns... global ghostwriter_end_dive ghostwriter_end_dive: movff ext_flash_address+0,ext_flash_log_pointer+0 movff ext_flash_address+1,ext_flash_log_pointer+1 movff ext_flash_address+2,ext_flash_log_pointer+2 ; save end-of-profile pointer to store in header movff menupos3,customview_divemode ; store last custom view btfss realdive ; dive longer then one minute goto ghostwriter_end_dive_common ; NO - discard everything ; In DEBUG compile, keep all simulated dives in logbook, Desat time, nofly, etc... ifndef __DEBUG btfsc simulatormode_active ; are we in simulator mode? goto ghostwriter_end_dive_common_sim ; YES - discard everything endif btfsc FLAG_apnoe_mode ; in Apnoe mode? goto ghostwriter_end_dive_common ; YES - discard everything ; Dive finished (and longer than one minute) btfsc FLAG_apnoe_mode ; calc max. depth (again) for very short apnoe dives call apnoe_calc_maxdepth ; calculate desaturation time movff last_surfpressure_30min+0,int_I_pres_surface+0 ; pass surface to desat routine ! movff last_surfpressure_30min+1,int_I_pres_surface+1 call deco_calc_dive_interval_1min ; calculate deco in surface mode call deco_calc_desaturation_time ; calculate desaturation time banksel common ; select ram bank 1 movlw 0xFD ; .... End-of-Profile bytes rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw 0xFD rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movff ext_flash_address+0,ext_flash_log_pointer+0 movff ext_flash_address+1,ext_flash_log_pointer+1 movff ext_flash_address+2,ext_flash_log_pointer+2 ; save end-of-profile pointer to store in header ; Set to first address again to store dive length ext_flash_dive_counter:3 rcall ghostwriter_load_pointer ; load ext_flash_address:3 from EEPROM .4-.6 incf_ext_flash_address_0x20 d'6' ; skip internal "0xFA 0xFA #Divenumber:2 0xFA 0xFA" Header ; Store dive length movf ext_flash_dive_counter+0,W call write_byte_ext_flash_plus_nodel ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) and does NOT delete 4kB page movf ext_flash_dive_counter+1,W call write_byte_ext_flash_plus_nodel ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) and does NOT delete 4kB page movf ext_flash_dive_counter+2,W call write_byte_ext_flash_plus_nodel ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) and does NOT delete 4kB page ; profile recording done ; Load total number of dives read_int_eeprom .2 movff EEDATA,lo read_int_eeprom .3 movff EEDATA,hi ; +1 ; increase total dive counter infsnz lo,F incf hi,F ; Store new number in EEPROM movff lo,EEDATA write_int_eeprom .2 movff hi,EEDATA write_int_eeprom .3 decf lo,F ; -1 ; Set ext_flash_address:3 to TOC entry of this dive ; 1st: 200000h-200FFFh -> lo=0 ; 2nd: 201000h-201FFFh -> lo=1 ; 3rd: 202000h-202FFFh -> lo=2 ; 255: 2FF000h-2FFFFFh -> lo=255 clrf ext_flash_address+0 clrf ext_flash_address+1 movlw 0x20 movwf ext_flash_address+2 movlw .16 mulwf lo ; lo*16 = offset to 0x2000 (up:hi) movf PRODL,W addwf ext_flash_address+1,F movf PRODH,W addwfc ext_flash_address+2,F ; Now, write header movlw 0xFA ; header start rcall ghostwrite_byte_header ; (this call will also delete the 4kB TOC entry first) movlw 0xFA rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; store pointer to begin of dive profile read_int_eeprom .4 movf EEDATA,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash read_int_eeprom .5 movf EEDATA,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash read_int_eeprom .6 movf EEDATA,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; store pointer to end of dive profile movf ext_flash_log_pointer+0,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf ext_flash_log_pointer+1,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf ext_flash_log_pointer+2,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; write rest of header movlw logbook_profile_version ; defined in hwos.inc rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Store dive length movf ext_flash_dive_counter+0,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf ext_flash_dive_counter+1,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf ext_flash_dive_counter+2,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash lfsr FSR0,start_year ; load base address of start-of-dive data movf POSTINC0,W ; year rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; month rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; day rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; hour rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; minute rcall ghostwrite_byte_header ; WREG -> header in ext. flash btfss FLAG_apnoe_mode ; store apnoe max or normal max (which is only max from the last descent) bra end_dive1 ; store normal depth movff apnoe_max_pressure+0,lo movff apnoe_max_pressure+1,hi call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] movff lo,apnoe_max_pressure+0 movff hi,apnoe_max_pressure+1 movf lo,W ; max. depth, low byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf hi,W ; max. depth, high byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash bra end_dive2 ; skip normal max. depth end_dive1: movff max_pressure+0,lo movff max_pressure+1,hi call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mbar] movff lo,max_pressure+0 movff hi,max_pressure+1 movf lo,W ; max. depth, low byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf hi,W ; max. depth, high byte rcall ghostwrite_byte_header ; WREG -> header in ext. flash end_dive2: movf divemins+0,W ; dive time minutes rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf divemins+1,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf divesecs,W ; dive time seconds rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff minimum_temperature+0,WREG ; minimum temperature rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff minimum_temperature+1,WREG rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff last_surfpressure_30min+0,WREG ; air pressure before dive rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff last_surfpressure_30min+1,WREG rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff int_O_desaturation_time+0,WREG ; desaturation time in minutes rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff int_O_desaturation_time+1,WREG rcall ghostwrite_byte_header ; WREG -> header in ext. flash btfsc FLAG_ccr_mode ; in CCR mode? bra end_dive_dil_gaslist ; YES - write diluent gas list btfsc FLAG_pscr_mode ; in pSCR mode? bra end_dive_dil_gaslist ; YES - write diluent gas list end_dive_oc_gaslist: ; write OC gases lfsr FSR0,opt_gas_O2_ratio-.1 ; set base address to (opt_gas_O2_ratio - 1) because of pre-increment statement bra end_dive_gaslist ; write all 5 OC gases end_dive_dil_gaslist: ; write diluents lfsr FSR0,opt_dil_O2_ratio-.1 ; set base address to (opt_dil_O2_ratio - 1) because of pre-increment statement ;bra end_dive_gaslist ; write all 5 diluents end_dive_gaslist: ; helper function for writing gas list entries ; ; Memory Map: ; ------------------------- ; opt_gas_O2_ratio res 5 ; opt_dil_O2_ratio res 5 ; opt_gas_He_ratio res 5 ; opt_dil_He_ratio res 5 ; opt_gas_type res 5 ; opt_dil_type res 5 ; opt_gas_change res 5 ; opt_dil_change res 5 ; movlw .5 ; 5 gases to store movwf lo ; use lo as counter end_dive_gaslist_loop: movf PREINC0,W ; increment base address and get O2 ratio into WREG rcall ghostwrite_byte_header ; store data movlw .10 ; offset for H2 ratios movf PLUSW0,W ; get H2 ratio into WREG rcall ghostwrite_byte_header ; store data movlw .30 ; offset for change depths movf PLUSW0,W ; get change depth into WREG rcall ghostwrite_byte_header ; store data movlw .20 ; offset for types movf PLUSW0,W ; get type into WREG rcall ghostwrite_byte_header ; store data decfsz lo ; decrement counter, did it became 0 ? bra end_dive_gaslist_loop ; NO - loop ;bra end_dive_oc_cc_common ; YES - done end_dive_oc_cc_common: movlw softwareversion_x ; firmware version rcall ghostwrite_byte_header movlw softwareversion_y rcall ghostwrite_byte_header movf batt_voltage+0,W ; battery voltage rcall ghostwrite_byte_header movf batt_voltage+1,W rcall ghostwrite_byte_header movf samplingrate,W ; Sampling rate btfsc FLAG_apnoe_mode ; Apnoe mode? movlw samplingrate_apnoe ; Apnoe sampling rate rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; CNS at beginning of dive movff CNS_start+0,WREG rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff CNS_start+1,WREG rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Gradient factor movff GF_start,WREG rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff int_O_gradient_factor+0,WREG ; value limited to 255, only lower byte in use rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Logbook offset call do_logoffset_common_read ; Read into lo:hi movf lo,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf hi,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Battery info at Byte 59 movf batt_percent,W ; 0-100 rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Store the setpoints lfsr FSR0,char_I_setpoint_cbar ; base address of ppO2 values lfsr FSR1,char_I_setpoint_change ; base address of change depths movlw .5 ; 5 setpoints to store movwf lo ; use lo as counter end_dive_sp_loop: movf POSTINC0,W ; get ppO2 value rcall ghostwrite_byte_header ; store ppO2 value movf POSTINC1,W ; get change depth rcall ghostwrite_byte_header ; store change depth decfsz lo ; decrement counter, did it became 0 ? bra end_dive_sp_loop ; NO - loop ; Store further data movff opt_salinity,WREG ; salinity (0-4%) rcall ghostwrite_byte_header ; store salinity movff int_O_CNS_fraction+0,WREG ; CNS value, low byte rcall ghostwrite_byte_header ; store CNS% movff int_O_CNS_fraction+1,WREG ; CNS value, high byte bcf WREG,int_warning_flag ; clear warning flag bcf WREG,int_attention_flag ; clear attention flag rcall ghostwrite_byte_header ; store CNS% movff avg_rel_pressure_total+0,WREG ; average depth rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff avg_rel_pressure_total+1,WREG ; average depth rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff total_divetime_seconds+0,WREG ; total dive time (regardless of start_dive_threshold) rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff total_divetime_seconds+1,WREG ; total dive time (regardless of start_dive_threshold) rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff char_I_GF_Low_percentage,WREG ; GF_lo movff char_I_deco_model,lo decfsz lo,F ; jump over next line if char_I_deco_model == 1 movff char_I_saturation_multiplier,WREG ; saturation multiplier rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff char_I_GF_High_percentage,WREG ; GF_hi movff char_I_deco_model,lo decfsz lo,F ; jump over next line if char_I_deco_model == 1 movff char_I_desaturation_multiplier,WREG ; desaturation multiplier rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff char_I_deco_model,WREG ; 0 = ZH-L16, 1 = ZH-L16-GF rcall ghostwrite_byte_header ; writes byte and increases address (no banking) read_int_eeprom .2 movf EEDATA,W rcall ghostwrite_byte_header ; total dive counter, low read_int_eeprom .3 movf EEDATA,W rcall ghostwrite_byte_header ; total dive counter, high movff opt_dive_mode,WREG rcall ghostwrite_byte_header ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR ; Store all tissue data available movlw .16 movwf lo lfsr FSR1,char_O_tissue_N2_saturation+0 end_dive_store_tissues_N2: movf POSTINC1,W bcf WREG,7 ; clear flag bit for ongassing/offgassing rcall ghostwrite_byte_header ; WREG -> header in ext. flash decfsz lo,F bra end_dive_store_tissues_N2 ; NO movlw .64 movwf lo lfsr FSR1,0x700 ; pres_tissue_N2+0 ; 16*4 Byte Float = 64 Bytes end_dive_store_tissues_N2_2: movf POSTINC1,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash decfsz lo,F bra end_dive_store_tissues_N2_2 ; NO movlw .16 movwf lo lfsr FSR1,char_O_tissue_He_saturation+0 end_dive_store_tissues_He: movf POSTINC1,W bcf WREG,7 ; clear flag bit for ongassing/offgassing rcall ghostwrite_byte_header ; WREG -> header in ext. flash decfsz lo,F bra end_dive_store_tissues_He ; NO movlw .64 movwf lo lfsr FSR1,0x740 ; pres_tissue_He+0 ; 16*4 Byte Float = 64 Bytes end_dive_store_tissues_He_2: movf POSTINC1,W rcall ghostwrite_byte_header ; WREG -> header in ext. flash decfsz lo,F bra end_dive_store_tissues_He_2 ; NO ; Some deco stuff movff char_I_depth_last_deco,WREG ; last stop [m] rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff char_I_deco_distance,WREG ; assumed distance to shown stop rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Last HUD data movff hud_battery_mv+0,WREG ; last HUD battery value rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff hud_battery_mv+1,WREG ; last HUD battery value rcall ghostwrite_byte_header ; WREG -> header in ext. flash movff hud_status_byte,WREG ; last HUD status rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Battery gauge registers [nAs] lfsr FSR0,battery_gauge ; load base address of battery gauge register movf POSTINC0,W ; get byte 0 rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; get byte 1 rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; get byte 2 rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; get byte 3 rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; get byte 4 rcall ghostwrite_byte_header ; WREG -> header in ext. flash movf POSTINC0,W ; get byte 5 rcall ghostwrite_byte_header ; WREG -> header in ext. flash ; Header stop movlw 0xFB rcall ghostwrite_byte_header ; WREG -> header in ext. flash movlw 0xFB rcall ghostwrite_byte_header ; WREG -> header in ext. flash call divemode_store_statistics ; store/update statistics for this unit clrf surface_interval+0 clrf surface_interval+1 ; clear surface interval timer ghostwriter_end_dive_common: ; Update ext_flash_log_pointer into EEPROM clrf EEADRH movff ext_flash_log_pointer+0,EEDATA write_int_eeprom .4 movff ext_flash_log_pointer+1,EEDATA write_int_eeprom .5 movff ext_flash_log_pointer+2,EEDATA write_int_eeprom .6 bcf simulatormode_active ; if we were in simulator mode ; In DEBUG compile, keep all simulated dives in logbook, Desat time, nofly, etc... ifndef __DEBUG btfsc restore_deco_data ; restore decodata? call deco_pull_tissues_from_vault banksel common ; bank 1 endif call update_battery_registers ; update battery registers into EEPROM goto surfloop ; and return to surface loop ghostwriter_end_dive_common_sim: tstfsz surface_interval+0 ; was interval zero? bra ghostwriter_end_dive_common_sim2 ; NO tstfsz surface_interval+1 ; was interval zero? bra ghostwriter_end_dive_common_sim2 ; NO bra ghostwriter_end_dive_common ; YES - done ghostwriter_end_dive_common_sim2: movf divemins+0,W addwf surface_interval+0,F movf divemins+1,W addwfc surface_interval+1 ; add simulated dive time to surface interval bra ghostwriter_end_dive_common ghostwriter_load_pointer: ; load ext_flash_address:3 from EEPROM .4-.6 clrf EEADRH ; make sure to select EEPROM bank 0 read_int_eeprom .4 movff EEDATA,ext_flash_address+0 read_int_eeprom .5 movff EEDATA,ext_flash_address+1 read_int_eeprom .6 movff EEDATA,ext_flash_address+2 return ghostwriter_short_header_init: ; proceed one page forward clrf EEDATA write_int_eeprom .4 ; ext_flash_address+0 = 0 movlw .16 addwf ext_flash_address+1,F movlw .0 addwfc ext_flash_address+2,F movlw 0x20 cpfseq ext_flash_address+2 ; at address 0x200000? bra ghostwriter_short_header_init2 ; NO clrf ext_flash_address+2 ; YES - rollover to 0x000000 ghostwriter_short_header_init2: movlw 0xF0 andwf ext_flash_address+1,F ; keep higher nibble, set lower nibble to 0 movff ext_flash_address+1,EEDATA write_int_eeprom .5 ; write new pointer movff ext_flash_address+2,EEDATA write_int_eeprom .6 ; write new pointer bra ghostwriter_short_header2 ; Done global ghostwriter_short_header ghostwriter_short_header: ; write short header with dive number into profile memory ; load pointer for profile storing into RAM (Updated in EEPROM after the dive) rcall ghostwriter_load_pointer ; load ext_flash_address:3 from EEPROM .4-.6 ; The following code is used to write a clean new dive after the previous hasn't been ; stored correctly. e.g. after a battery fail during the dive call ext_flash_byte_read_plus_0x20 ; into ext_flash_rw incfsz ext_flash_rw,F bra ghostwriter_short_header_init ; not 0xFF -> init page call ext_flash_byte_read_plus_0x20 ; into ext_flash_rw incfsz ext_flash_rw,F bra ghostwriter_short_header_init ; not 0xFF -> init page ghostwriter_short_header2: ; All ok, reload the pointer and start rcall ghostwriter_load_pointer ; load ext_flash_address:3 from EEPROM .4-.6 ; Clear dive length counter clrf ext_flash_dive_counter+0 clrf ext_flash_dive_counter+1 clrf ext_flash_dive_counter+2 ; Write short header with dive number into profile memory movlw 0xFA rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw 0xFA rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash ; Load total number of dives (low byte only) read_int_eeprom .2 incf EEDATA,W ; +1 rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash read_int_eeprom .3 movf EEDATA,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw 0xFA rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw 0xFA rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash ; Keep room for dive length ext_flash_dive_counter:3 (Stored at the end of the dive) ; Writing 0xFF three times here is mandatory ; - 0xFF can be overwritten after the dive ; - ghostwrite_byte_profile takes care of 4kB Page switching ; - fixes an issue when we are at exactly 0xXXX000 here... movlw 0xFF call write_byte_ext_flash_plus_nocnt ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) movlw 0xFF call write_byte_ext_flash_plus_nocnt ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) movlw 0xFF call write_byte_ext_flash_plus_nocnt ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) movf samplingrate,W ; sampling rate btfsc FLAG_apnoe_mode ; apnoe mode? movlw samplingrate_apnoe ; apnoe sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .7 ; number of divisors rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .0 ; type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_temperature rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_temperature ; divisor temperature rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .1 ; Type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_deco rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_deco ; divisor deco data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .2 ; type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_gf rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_gf ; divisor gf rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .3 ; type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_ppo2_sensors rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_ppo2_sensors ; divisor ppO2 btfss FLAG_ccr_mode ; =1: CCR mode (Fixed ppO2 or Sensor) active movlw .0 ; no ppO2 data in OC mode rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .4 ; type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_decoplan rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_decoplan ; divisor debug rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .5 ; Type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_cns rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_cns ; divisor CNS rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw .6 ; Type rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw infolength_tank rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movlw div_tank ; divisor tank rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash return divemode_store_statistics: ; store/update statistics for this unit call vault_decodata_into_eeprom ; update deco data call do_logoffset_common_read ; existing logbook offset into lo:hi tstfsz lo ; lo=0? bra change_logbook_offset1 ; NO - adjust offset tstfsz hi ; hi=0? bra change_logbook_offset1 ; NO - adjust offset bra change_logbook_offset2 ; lo=0 and hi=0 -> skip offset routine change_logbook_offset1: movlw d'1' addwf lo movlw d'0' addwfc hi call do_logoffset_common_write ; lo:hi -> EEPROM change_logbook_offset2: ; Clear lastdive:4 banksel lastdive_time+0 clrf lastdive_time+0 clrf lastdive_time+1 clrf lastdive_time+2 clrf lastdive_time+3 movff divemins+0,lastdive_duration+0 movff divemins+1,lastdive_duration+1 movff divesecs, lastdive_duration+2 movff max_pressure+0,lastdive_maxdepth+0 movff max_pressure+1,lastdive_maxdepth+1 banksel common ; Add more here... return END