Mercurial > public > hwos_code
view src/sleepmode.asm @ 620:cd986267a5ca
potential compass bug "fixed"
author | heinrichsweikamp |
---|---|
date | Fri, 22 Feb 2019 16:30:05 +0100 |
parents | ca4556fb60b9 |
children | c40025d8e750 be8787f2034d |
line wrap: on
line source
;============================================================================= ; ; File sleepmode.asm Version 2.99e ; ; Sleepmode ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================== ; HISTORY ; 2011-08-12 : [mH] moving from OSTC code #include "hwos.inc" ; Mandatory header #include "shared_definitions.h" ; Mailbox from/to p2_deco.c #include "surfmode.inc" #include "tft.inc" #include "isr.inc" #include "start.inc" #include "adc_lightsensor.inc" #include "math.inc" #include "ms5541.inc" #include "wait.inc" #include "eeprom_rs232.inc" #include "external_flash.inc" #include "ghostwriter.inc" #include "i2c.inc" #include "mcp.inc" extern vault_decodata_into_eeprom ;---- Private local variables ------------------------------------------------- CBLOCK local1 ; max size is 16 Byte !!! sm_temp1 ; sleepmode temporary 1 sm_temp2 ; sleepmode temporary 2 sm_timer1 ; timer for pressure check every 10 seconds sm_timer2 ; timer for 10 minutes tasks (updating of tissues) sm_timer3 ; timer for 15 minutes tasks (updating of surface pressure) ENDC ; used: 5 byte, remaining: 11 byte slmode CODE ;============================================================================== global sleeploop sleeploop: ; enter sleep mode call disable_ir_s8 ; IR/S8 off call mcp_sleep bcf LEDg bcf LEDr call TFT_Display_FadeOut call TFT_DisplayOff ; display off IFDEF _screendump bcf enable_screen_dumps ; =1: Ignore vin_usb, wait for "l" command (screen dump) ENDIF call disable_rs232 ; USB off call vault_decodata_into_eeprom ; store deco data call ext_flash_enable_protection ; enable write protection for external flash call update_battery_registers ; update battery registers into EEPROM clrf sm_temp1 clrf sm_temp2 clrf sm_timer1 clrf sm_timer2 clrf sm_timer3 call speed_normal bsf no_sensor_int ; inhibit sensor interrupts clrf ADCON0 ; power-down ADC module sleeploop_pre: bcf deep_sleep ; normal sleep mode call I2C_sleep_accelerometer call I2C_sleep_compass btfss analog_switches ; OSTC with analog switches? bra sleeploop_loop ; NO - no analog switches bsf power_sw1 btfss power_sw1 bra $-4 bsf power_sw2 btfss power_sw2 bra $-4 movlw .4 ; wait for button circuity movwf sm_temp1 ; used as temp bcf onesecupdate sleeploop_pre1: rcall sleepmode_sleep btfss onesecupdate ; wait 1 second bra sleeploop_pre1 bcf onesecupdate decfsz sm_temp1,F bra sleeploop_pre1 movlw .32 ; wait for button circuity movwf sm_temp1 ; used as temp sleeploop_pre2: call get_analog_switches decfsz sm_temp1,F bra sleeploop_pre2 bcf PIR1,TMR1IF bcf INTCON,INT0IF bcf INTCON3,INT1IF bcf PIR5,TMR7IF bcf switch_left bcf switch_right bcf analog_sw2_pressed bcf analog_sw1_pressed bsf PIE1,0 ; (re)start timer 1 interrupt bsf PIE2,1 ; (re)start timer 2 interrupt bsf PIE5,3 ; (re)start timer 7 interrupt bsf INTCON,4 ; (re)start INT0 interrupt bsf INTCON3,3 ; (re)start INT1 interrupt sleeploop_loop: btfsc onesecupdate ; one second in sleep? rcall onesec_sleep ; check switches, check pressure sensor, etc. btfss sleepmode ; wake up? (This bit will be set in other routines) goto restart ; YES btfsc deep_sleep ; enter deep sleep? bra deepsleep ; YES no_deepsleep: rcall sleepmode_sleep ; wait at least 35 ms (every 62.5ms timer7 wakeup) ; Any button pressed in sleep? ; btfsc switch_left ; rcall onesec_sleep1a ; btfsc switch_right ; rcall onesec_sleep1a ; ; btfss sleepmode ; wake up? (this bit will be set in other routines) ; goto restart ; YES bra sleeploop_loop ; do loop until something happens deepsleep: btfss analog_switches bra no_deepsleep ; no analog switches, no deep sleep required bcf PIE1,0 ; stop timer 1 interrupt bcf PIE2,1 ; stop timer 2 interrupt bcf PIE5,3 ; stop timer 7 interrupt bcf INTCON,4 ; stop INT0 interrupt bcf INTCON3,3 ; stop INT1 interrupt bcf power_sw1 bcf power_sw2 rcall deepsleep_get_accel ; read accelerometer into WREG movwf sm_temp1 ; store init value deepsleep_loop: btfsc onesecupdate ; one second in sleep? rcall onesec_deepsleep ; YES - check accelerometer btfsc onesecupdate ; one second in sleep? rcall onesec_sleep ; YES - check switches, check pressure sensor, etc. rcall sleepmode_sleep btfss deep_sleep ; enter normal sleep mode? bra sleeploop_pre ; Yes bra deepsleep_loop ; do loop until something happens onesec_deepsleep: rcall deepsleep_get_accel ; read accelerometer into WREG subwf sm_temp1,W ; sm_temp1 - accel_DZ+0 -> WREG btfsc STATUS,N ; result negative? negf WREG ; YES - negate it movwf sm_temp2 ; change of acceleration in Z-axis movlw .50 ; threshold (mg) cpfslt sm_temp2 ; bigger then the threshold? bcf deep_sleep ; YES ; extern piezo_config_tx ; movff sm_temp1,WREG ; call piezo_config_tx ; movff accel_DZ+0,WREG ; call piezo_config_tx ; movff sm_temp2,WREG ; call piezo_config_tx return deepsleep_get_accel: call I2C_init_compass ; required for compass1 call I2C_init_accelerometer ; required for compass2 call I2C_RX_accelerometer ; read accelerometer call I2C_sleep_compass ; required for compass1 call I2C_sleep_accelerometer ; required for compass2 movff accel_DZ+0,WREG return onehour_sleep: call update_battery_registers ; update battery registers into EEPROM call vault_decodata_into_eeprom ; update deco data bcf onehourupdate ; all done return onemin_sleep: btfsc onehourupdate ; one hour in sleep? rcall onehour_sleep ; YES btfsc battery_gauge_available call get_battery_voltage ; check for charger ;---- update tissues and CNS every 10 minutes when gradient factor is 0 (no supersaturation in any tissue any more) movff int_O_gradient_factor+0,WREG ; get gradient factor, only the lower byte is used for the value tstfsz WREG ; gradient factor = 0? bra onemin_sleep1 ; NO - continue with air pressure compensation incf sm_timer2,F ; count-up... movlw d'9' ; ...to 9 cpfsgt sm_timer2 ; 10 minutes over? bra onemin_sleep1 ; NO - continue with air pressure compensation clrf sm_timer2 ; reset counter SAFE_2BYTE_COPY amb_pressure, int_I_pres_respiration ; copy pressure to deco routine call deco_calc_dive_interval_10min ; calculate 10 minutes under surface conditions banksel common onemin_sleep1: ;---- adjust air pressure compensation any 15 minutes incf sm_timer3,F ; count-up... movlw d'14' ; ...to 14 cpfsgt sm_timer3 ; 15 minutes over? bra onemin_sleep2 ; NO - continue with every-minute-tasks ; Tasks every 15 minutes in sleep bsf deep_sleep ; enter deep-sleep mode clrf sm_timer3 ; reset counter SAFE_2BYTE_COPY last_surfpressure_15min, last_surfpressure_30min ; save older air pressure SAFE_2BYTE_COPY amb_pressure, last_surfpressure_15min ; save new air pressure 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_15min+0,sub_b+0 movff last_surfpressure_15min+1,sub_b+1 call subU16 ; sub_c = sub_a - sub_b btfss neg_flag ; Is 1080mbar < amb_pressure ? bra onemin_sleep2 ; 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_15min+0 ; max. "allowed" air pressure in mbar movlw HIGH max_surfpressure movff WREG,last_surfpressure_15min+1 ; max. "allowed" air pressure in mbar onemin_sleep2: ; Tasks every minute in sleep ;---- update tissues and CNS every minute when gradient factor is >0 (supersaturation in at least one tissue) movff int_O_gradient_factor+0,WREG ; get gradient factor, only the lower byte is used for the value tstfsz WREG ; gradient factor = 0? bra onemin_sleep3 ; NO - do tissue update on 1 minute schedule bra onemin_sleep4 ; YES - tissue update is done on 10 minutes schedule onemin_sleep3: SAFE_2BYTE_COPY amb_pressure, int_I_pres_respiration ; copy pressure to deco routine call deco_calc_dive_interval_1min ; calculate 1 minute under surface conditions banksel common onemin_sleep4: bcf oneminupdate ; all done return onesec_sleep: btfsc oneminupdate ; one minute in sleep? rcall onemin_sleep ; YES - do one-minute tasks, e.g. calculate desaturation btfsc battery_gauge_available call get_battery_voltage ; check for charger incf sm_timer1,F ; counts to #test_pressure_in_sleep (10) movlw d'10' cpfsgt sm_timer1 ; here: temp variable bra onesec_sleep1 ; #test_pressure_in_sleep not done yet clrf sm_timer1 ; clear counter rcall pressuretest_sleep_fast ; Gets pressure without averaging (faster!) ; compare current ambient pressure with wake_up_from_sleep movlw LOW wake_up_from_sleep movwf sub_a+0 ; power on if ambient pressure is greater threshold movlw HIGH wake_up_from_sleep movwf sub_a+1 ; power on if ambient pressure is greater threshold SAFE_2BYTE_COPY amb_pressure, sub_b call subU16 ; is (1160mbar - averaged(amb_pressure)) < 0 ? btfsc neg_flag ; wake up from sleep? bra onesec_sleep1a ; YES - skip button checks, wake up! btfsc battery_gauge_available bra onesec_sleep1 ; no wake-up with cR hardware btfsc vusb_in ; USB plugged in? bra onesec_sleep1a ; YES - skip button checks, wake up onesec_sleep1: bcf onesecupdate ; clear flag btfsc switch_left ; left switch pressed? bra onesec_sleep1a ; YES btfsc switch_right ; right switch pressed? bra onesec_sleep1a ; YES return ; NO to both - done onesec_sleep1a: ; at least one button pressed or amb_pressure -> wake_up_from_sleep bcf sleepmode ; wake up SAFE_2BYTE_COPY last_surfpressure_30min, amb_pressure ; copy for compatibility movlw .0 movff WREG,sensor_state_counter ; reset sensor state counter bcf no_sensor_int ; normal sensor interrupt mode return pressuretest_sleep_fast: ; get pressure without averaging (faster to save some power in sleep mode) banksel isr_backup ; back to Bank0 ISR data clrf amb_pressure_avg+0 ; clear pressure average registers clrf amb_pressure_avg+1 clrf temperature_avg+0 ; clear temperature average registers clrf temperature_avg+1 call get_temperature_start ; start temperature integration (73.5 us) banksel common rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) banksel isr_backup ; back to Bank0 ISR data call get_temperature_value ; state 1: get temperature call get_pressure_start ; start pressure integration banksel common rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) banksel isr_backup ; back to bank0 ISR data call get_pressure_value ; state2: get pressure (51 us) call calculate_compensation ; calculate temperature compensated pressure (27 us) banksel common SAFE_2BYTE_COPY amb_pressure_avg, amb_pressure ; copy for compatibility return sleepmode_sleep: banksel 0xF16 ; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM clrf T7GCON ; reset timer7 gate control register movlw b'10001101' ; 1:1 prescaler -> 2 seconds @ 32768 Hz, not synced movwf T7CON sleep sleep clrf T7GCON ; reset timer7 gate control register movlw b'10001001' ; 1:1 prescaler -> 2 seconds @ 32768Hz, synced movwf T7CON banksel common ; back to bank1 return END