view src/sleepmode.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 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