Mercurial > public > hwos_code
view src/sleepmode.asm @ 623:c40025d8e750
3.03 beta released
author | heinrichsweikamp |
---|---|
date | Mon, 03 Jun 2019 14:01:48 +0200 |
parents | ca4556fb60b9 |
children | cd58f7fc86db |
line wrap: on
line source
;============================================================================= ; ; File sleepmode.asm combined next generation V3.03.1 ; ; Sleep Mode ; ; 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 "start.inc" #include "adc_lightsensor.inc" #include "math.inc" #include "ms5541.inc" #include "eeprom_rs232.inc" #include "external_flash.inc" #include "ghostwriter.inc" #include "i2c.inc" #include "mcp.inc" #include "wait.inc" extern vault_decodata_into_eeprom extern power_up_switches ; from hwos.asm ;---- Private local Variables ------------------------------------------------- CBLOCK local1 ; max size is 16 Byte !!! accel_reference ; acceleration reference value for detecting movement / terminating deep sleep sm_timer_10sec ; timer for 10 seconds tasks (pressure check) sm_timer_10min ; timer for 10 minutes tasks (tissue updating) sm_timer_15min ; timer for 15 minutes tasks (entering deep sleep) loop_counter ; loop counter, used in init_avg_switches routine sm_flags ; local flags ENDC ; used: 6 byte, remaining: 10 byte ;---- Private local Flags ----------------------------------------------------- #DEFINE deep_sleep sm_flags,0 ; =1: in deep sleep mode, =0: normal sleep #DEFINE desat_on_10_mins sm_flags,1 ; =1: calculate desaturation every 10 minutes, =0: every minute ; sm_flags,2 ; unused ; sm_flags,3 ; unused ; sm_flags,4 ; unused ; sm_flags,5 ; unused ; sm_flags,6 ; unused ; sm_flags,7 ; unused slmode CODE ;============================================================================== global sleeploop sleeploop: clrf STKPTR ; clear return addresses stack call request_speed_normal ; request CPU speed switch to normal speed bcf LEDg ; turn off green LED / release reset to RX circuitry bcf LEDr ; turn off red LED IFDEF _screendump bcf screen_dump_avail ; disable screen dump function ENDIF bsf sleepmode ; flag being in sleep mode bsf block_sensor_interrupt ; suspend ISR from executing sensor interrupts IFDEF _external_sensor call disable_ir_s8 ; power-down IR/S8 interrupts call mcp_sleep ; power-down RX power supply ENDIF clrf ADCON0 ; power-down ADC module call TFT_Display_FadeOut ; power-down backlight call TFT_DisplayOff ; power-down display call disable_rs232 ; power-down USB call I2C_sleep_accelerometer ; power-down accelerometer call I2C_sleep_compass ; power-down compass call vault_decodata_into_eeprom ; store deco data call ext_flash_enable_protection ; enable write protection on external flash call update_battery_registers ; update battery registers into EEPROM clrf sm_timer_10sec ; clear 10 seconds timer clrf sm_timer_10min ; clear 10 minutes timer clrf sm_timer_15min ; clear 15 minutes timer clrf sm_flags ; clear all local flags sleeploop_loop: btfsc trigger_full_second ; one second in sleep? rcall one_sec_sleep ; YES - check switches, pressure sensor, etc. btfss sleepmode ; shall terminate sleep mode? bra sleeploop_exit ; YES rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) btfss deep_sleep ; shall enter deep sleep? bra sleeploop_loop ; NO - remain in normal sleep loop ;bra deepsleep_pre ; YES - enter deep sleep loop deepsleep_pre: bcf PIE1,0 ; disable timer 1 interrupt bcf PIE2,1 ; disable timer 2 interrupt bcf PIE5,3 ; disable timer 7 interrupt bcf INTCON,4 ; disable INT0 interrupt bcf INTCON3,3 ; disable INT1 interrupt bcf power_sw1 ; power-down switch 1 bcf power_sw2 ; power-down switch 2 rcall deepsleep_get_accel ; read accelerometer into WREG movwf accel_reference ; store as reference value deepsleep_loop: btfsc trigger_full_second ; one second in deep sleep? rcall check_accelerometer ; YES - check accelerometer btfsc trigger_full_second ; one second in deep sleep? rcall one_sec_sleep ; YES - check switches, check pressure sensor, etc. rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) btfss sleepmode ; shall leave sleep mode? bcf deep_sleep ; YES - leave deep sleep mode then, too btfsc deep_sleep ; shall leave deep sleep mode? bra deepsleep_loop ; NO - loop in deep sleep loop call power_up_switches ; turn on the analog switches rcall init_avg_switches ; initialize the averaging system bsf PIE1,0 ; enable timer 1 interrupt bsf PIE2,1 ; enable timer 2 interrupt bsf PIE5,3 ; enable timer 7 interrupt bsf INTCON,4 ; enable INT0 interrupt bsf INTCON3,3 ; enable INT1 interrupt bra sleeploop_loop ; enter normal sleep loop sleeploop_exit: bcf switch_left ; eventually clear left button event bcf switch_right ; eventually clear right button event movlw .0 ; reset ISR sensor state machine movff WREG,sensor_state_counter ; ... bcf PIR5,TMR7IF ; clear timer 7, driving the ISR sensor interrupts bcf block_sensor_interrupt ; re-enable execution of the ISR sensor interrupts goto restart ; restart one_sec_sleep: ; tasks every second in sleep mode bcf trigger_full_second ; clear trigger flag btfsc switch_left ; left switch pressed? bcf sleepmode ; YES - terminate sleep mode btfsc switch_right ; right switch pressed? bcf sleepmode ; YES - terminate sleep mode btfsc battery_gauge_available ; is a battery gauge IC available? bra one_sec_sleep_1 ; YES - check for charger btfsc vusb_in ; NO - USB plugged in? bcf sleepmode ; YES - terminate sleep mode bra one_sec_sleep_2 ; - continue one_sec_sleep_1: call get_battery_voltage ; check for charger one_sec_sleep_2: incf sm_timer_10sec,F ; increment 10 seconds timer movlw .10 ; load a 10 into WREG cpfslt sm_timer_10sec ; timer < 10 yet? rcall ten_sec_sleep ; NO - do the every 10 second tasks btfsc trigger_full_minute ; one minute in sleep? rcall one_min_sleep ; YES - do the every minute tasks btfsc trigger_full_hour ; one hour in sleep? rcall one_hour_sleep ; YES - do the every hour tasks return ; done ten_sec_sleep: ; tasks every 10 seconds in sleep mode clrf sm_timer_10sec ; clear timer rcall pressuretest_sleep_fast ; get pressure without averaging (faster) MOVLI wake_up_from_sleep,sub_a ; load wake-up pressure (1160 mbar) into sub_a MOVII pressure_abs, sub_b ; load current absolute pressure into sub_b call cmpU16 ; sub_a - sub_b = wake-up pressure - current absolute pressure btfsc neg_flag ; is the current absolute pressure > 1160 mbar ? bcf sleepmode ; YES - terminate sleep mode return ; done one_min_sleep: ; tasks every minute in sleep mode bcf trigger_full_minute ; clear flag ; tick the 10 minutes timer incf sm_timer_10min,F ; increment 10 minutes timer movlw .10 ; load a 10 into WREG cpfslt sm_timer_10min ; timer < 10 yet? rcall ten_min_sleep ; NO - do the every 10 minutes tasks ; the 15 minutes timer only ticks on OSTC with analog switches btfss analog_switches ; OSTC with analog switches? bra one_min_sleep_1 ; NO - no analog switches, no deep sleep required ; the 15 minutes timer also ticks only when not in deep sleep btfsc deep_sleep ; in deep sleep mode? bra one_min_sleep_1 ; YES - already in deep sleep ; tick the 15 minutes timer incf sm_timer_15min,F ; increment 15 minutes timer movlw .15 ; load a 15 into WREG cpfslt sm_timer_15min ; timer < 15 yet? rcall fifteen_min_sleep ; NO - do the every 15 minute tasks one_min_sleep_1: ; continue tasks every minute btfsc desat_on_10_mins ; shall do desaturation calculation on 10 minute intervals? return ; YES - that's not here then, so done call deco_calc_dive_interval_1min ; NO - calculate 1 minute at surface conditions (C-code) banksel common ; - back to bank common return ; - done ten_min_sleep: ; tasks every 10 minutes in sleep mode clrf sm_timer_10min ; reset timer to 0 call sample_surface_pressure ; sample surface pressure and update ISR and deco engine btfss desat_on_10_mins ; shall do desaturation calculation on 10 minute intervals? bra ten_min_sleep_1 ; NO - continue checking if schedule can be switched to 10 minutes call deco_calc_dive_interval_10min ; YES - calculate 10 minutes at surface conditions (C-code) banksel common ; - back to bank common return ; - done ten_min_sleep_1: movff int_O_lead_supersat+0,WREG ; get leading tissue's supersaturation (only the lower byte is used for the value) bsf desat_on_10_mins ; switch to 10 minute intervals by default tstfsz WREG ; gradient factor = 0 ? bcf desat_on_10_mins ; NO - stay on 1 minute intervals return ; done fifteen_min_sleep: ; tasks every 15 minutes in sleep mode clrf sm_timer_15min ; reset timer to 0 bsf deep_sleep ; enable deep-sleep mode return one_hour_sleep: ; tasks every hour in sleep mode mode bcf trigger_full_hour ; clear one hour flag call update_battery_registers ; update battery registers into EEPROM call vault_decodata_into_eeprom ; update tissue pressures into EEPROM return init_avg_switches: ; pause 4 seconds using CPU sleep mode to conserve on battery movlw .4 ; time to pause movwf loop_counter ; initialize loop counter bcf trigger_full_second ; clear 'one second elapsed' flag activate_switches_1: rcall sleepmode_sleep ; wait at least 35 ms (every 62.5 ms timer7 wakeup) btfss trigger_full_second ; did 1 second elapsed meanwhile? bra activate_switches_1 ; NO - loop bcf trigger_full_second ; YES - clear flag decfsz loop_counter,F ; - decrement loop counter, done? bra activate_switches_1 ; NO - loop ; initialize the averaging system movlw .32 ; number of readout cycles movwf loop_counter ; initialize loop counter activate_switches_2: call get_analog_switches ; do a analog switch readout decfsz loop_counter,F ; decrement loop counter, done? bra activate_switches_2 ; NO - loop ; clear all button events that may have intermediately occurred bcf PIR1,TMR1IF ; clear button-hold-down timer bcf INTCON,INT0IF ; clear right button activity bcf INTCON3,INT1IF ; clear left button activity bcf analog_sw1_pressed ; clear analog switch 1 activity bcf analog_sw2_pressed ; clear analog switch 2 activity bcf switch_right ; clear right button event bcf switch_left ; clear left button event ; done return check_accelerometer: rcall deepsleep_get_accel ; read accelerometer into WREG subwf accel_reference,W ; reference value - accel_DZ+0 -> WREG btfsc STATUS,N ; result negative? negf WREG ; YES - negate it movwf lo ; save as change of acceleration in Z-axis movlw .50 ; load threshold (mg) cpfslt lo ; change of acceleration > threshold ? bcf deep_sleep ; YES - terminate deep sleep mode return ; done deepsleep_get_accel: call I2C_init_compass ; start compass, required for compass1 call I2C_init_accelerometer ; start accelerometer, required for compass2 call I2C_RX_accelerometer ; read accelerometer call I2C_sleep_compass ; shut down compass, required for compass1 call I2C_sleep_accelerometer ; shut down accelerometer, required for compass2 movff accel_DZ+0,WREG ; transfer result to WREG return ; done pressuretest_sleep_fast: ; get pressure without averaging (faster to save some power in sleep mode) banksel isr_backup ; select bank ISR data CLRI pressure_abs_avg ; clear pressure average register CLRI temperature_avg ; clear temperature average register call get_temperature_start ; start temperature integration (73.5 us) 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) call get_temperature_value ; state 1: get temperature call get_pressure_start ; start pressure integration 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) call get_pressure_value ; state2: get pressure (51 us) call calculate_compensation ; calculate temperature compensated pressure (27 us) MOVII pressure_abs_avg,pressure_abs ; get result, bypassing the averaging banksel common ; back to bank common return sleepmode_sleep: movff BSR,BSR_backup ; backup BSR banksel T7GCON ; switch bank, T7* is outside 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 @ 32768 Hz, synced movwf T7CON movff BSR_backup,BSR ; restore BSR return END