diff code_part1/OSTC_code_asm_part1/adc_rtc.asm @ 0:96a35aeda5f2

Initial setup
author heinrichsweikamp
date Tue, 12 Jan 2010 15:05:59 +0100
parents
children 588a969a0cae
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/code_part1/OSTC_code_asm_part1/adc_rtc.asm	Tue Jan 12 15:05:59 2010 +0100
@@ -0,0 +1,242 @@
+
+; OSTC - diving computer code
+; Copyright (C) 2008 HeinrichsWeikamp GbR
+
+;    This program is free software: you can redistribute it and/or modify
+;    it under the terms of the GNU General Public License as published by
+;    the Free Software Foundation, either version 3 of the License, or
+;    (at your option) any later version.
+
+;    This program is distributed in the hope that it will be useful,
+;    but WITHOUT ANY WARRANTY; without even the implied warranty of
+;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;    GNU General Public License for more details.
+
+;    You should have received a copy of the GNU General Public License
+;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+; routines for AD converter, Realtime clock initialisation
+; written by: Matthias Heinrichs, info@heinrichsweikamp.com
+; written: 10/30/05
+; last updated: 05/15/08
+; known bugs:
+; ToDo: 
+
+get_battery_voltage:			; starts ADC and waits until fnished
+	bsf		ADCON0,0			; power on ADC
+	nop
+	bsf		ADCON0,1			; start ADC
+get_battery_voltage2:
+	btfsc	ADCON0,1			; Wait...
+	bra		get_battery_voltage2
+
+; 3.3V/1024=3,2227mV Input/Bit=9,6680mV Battery/Bit. 
+; Example: 434*9,6680mV=4195,9mV Battery. 
+
+	movff	ADRESH,xA+1
+	movff	ADRESL,xA+0
+	movlw	LOW		d'966'				
+	movwf	xB+0
+	movlw	HIGH	d'966'				
+	movwf	xB+1
+	call	mult16x16			; AD_Result*966
+	movlw	d'100'
+	movwf	xB+0
+	clrf	xB+1
+	call	div32x16		  ;xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+	movff	xC+0,batt_voltage+0	; store value
+	movff	xC+1,batt_voltage+1
+	bcf		ADCON0,0			; power off ADC
+
+	; Check if we should enter deep-sleep mode
+	
+	movff	batt_voltage+0,sub_b+0	
+	movff	batt_voltage+1,sub_b+1
+	movlw	LOW		d'2600'			; must be greater then 2600mV...
+	movwf	sub_a+0
+	movlw	HIGH	d'2600'
+	movwf	sub_a+1
+	call	sub16					;  sub_c = sub_a - sub_b
+	bcf		enter_error_sleep		; Clear flag
+	btfsc	neg_flag				; neg_flag=1 if eeprom40:41 < 2000
+	bra		get_battery_voltage3	; Battery in OK range
+	
+	movlw	d'2'
+	movwf	fatal_error_code		; Battery very low!
+	bsf		enter_error_sleep		; enter error routine
+
+get_battery_voltage3:	
+	movff	amb_pressure+0,sub_b+0	
+	movff	amb_pressure+1,sub_b+1
+	movlw	LOW		d'15001'			; must be lower then 15001mBar
+	movwf	sub_a+0
+	movlw	HIGH	d'15001'
+	movwf	sub_a+1
+	call	sub16					;  sub_c = sub_a - sub_b
+	bcf		enter_error_sleep		; Clear flag
+	btfss	neg_flag				; 
+	bra		get_battery_voltage4	; Pressure in OK range
+	
+	movlw	d'3'
+	movwf	fatal_error_code		; too deep
+	bsf		enter_error_sleep		; enter error routine
+	; Continue with rest of routine
+
+get_battery_voltage4:
+	; check if the battery control memory needs to be initialised!
+	bcf		initialize_battery1		; clear check-flags
+	bcf		initialize_battery2
+
+	read_int_eeprom d'40'			; get lowest battery voltage seen in mV
+	movff	EEDATA,sub_b+0
+	read_int_eeprom d'41'
+	movff	EEDATA,sub_b+1
+	
+	movlw	LOW		d'2000'			; must be greater then 2000mV...
+	movwf	sub_a+0
+	movlw	HIGH	d'2000'
+	movwf	sub_a+1
+	call	sub16					;  sub_c = sub_a - sub_b
+	btfss	neg_flag				; neg_flag=1 if eeprom40:41 < 2000
+	bsf		initialize_battery1		; battery need to be initialised
+
+	movlw	LOW		d'4500'			; must be lower then 4500mV...
+	movwf	sub_a+0
+	movlw	HIGH	d'4500'
+	movwf	sub_a+1
+	call	sub16					;  sub_c = sub_a - sub_b
+	btfss	neg_flag				; neg_flag=1 if eeprom40:41 < 4500
+	bsf		initialize_battery2		; battery need to be initialised
+	
+	btfss	initialize_battery1		; battery need to be initialised?
+	bra		get_battery_no_init		; No, we have already valid values, just check for new extremas
+
+	btfss	initialize_battery2		; battery need to be initialised?
+	bra		get_battery_no_init		; No, we have already valid values, just check for new extremas
+	
+	; Init EEPROM for battery control
+	; Reset lowest battery seen
+	movlw	LOW			d'4200'		; reset to 4.2V
+	movwf	EEDATA
+	write_int_eeprom	d'40'
+	movlw	HIGH		d'4200'		; reset to 4.2V
+	movwf	EEDATA
+	write_int_eeprom	d'41'
+	movff	month,EEDATA
+	write_int_eeprom	d'42'
+	movff	day,EEDATA
+	write_int_eeprom	d'43'
+	movff	year,EEDATA
+	write_int_eeprom	d'44'
+	movff	temperature+0,EEDATA
+	write_int_eeprom	d'45'
+	movff	temperature+1,EEDATA
+	write_int_eeprom	d'46'
+	; Reset charge statistics
+	clrf	EEDATA					; last complete charge
+	write_int_eeprom	d'47'		
+	clrf	EEDATA					; last complete charge
+	write_int_eeprom	d'48'		
+	clrf	EEDATA					; last complete charge
+	write_int_eeprom	d'49'		
+	clrf	EEDATA					; total cycles
+	write_int_eeprom	d'50'		
+	clrf	EEDATA					; total cycles
+	write_int_eeprom	d'51'		
+	clrf	EEDATA					; total complete cycles
+	write_int_eeprom	d'52'		
+	clrf	EEDATA					; total complete cycles
+	write_int_eeprom	d'53'		
+	; Reset temperature extremas
+	movff	temperature+0,EEDATA	; Reset mimimum extrema
+	write_int_eeprom	d'54'
+	movff	temperature+1,EEDATA
+	write_int_eeprom	d'55'
+	movff	month,EEDATA
+	write_int_eeprom	d'56'
+	movff	day,EEDATA
+	write_int_eeprom	d'57'
+	movff	year,EEDATA
+	write_int_eeprom	d'58'
+	movff	temperature+0,EEDATA	; Reset maximum extrema
+	write_int_eeprom	d'59'
+	movff	temperature+1,EEDATA
+	write_int_eeprom	d'60'
+	movff	month,EEDATA
+	write_int_eeprom	d'61'
+	movff	day,EEDATA
+	write_int_eeprom	d'62'
+	movff	year,EEDATA
+	write_int_eeprom	d'63'
+	
+get_battery_no_init:	
+	read_int_eeprom d'40'			; get lowest battery voltage seen in mV
+	movff	EEDATA,sub_b+0
+	read_int_eeprom d'41'
+	movff	EEDATA,sub_b+1
+	movff	batt_voltage+0,sub_a+0
+	movff	batt_voltage+1,sub_a+1
+	call	sub16					; sub_c = sub_a - sub_b
+	btfss	neg_flag				; new lowest battery voltage?
+	return							; no, quit routine
+	; Yes, store new value together with the date and temperature values
+	movff	batt_voltage+0,EEDATA
+	write_int_eeprom	d'40'
+	movff	batt_voltage+1,EEDATA
+	write_int_eeprom	d'41'
+	movff	month,EEDATA
+	write_int_eeprom	d'42'
+	movff	day,EEDATA
+	write_int_eeprom	d'43'
+	movff	year,EEDATA
+	write_int_eeprom	d'44'
+	movff	temperature+0,EEDATA
+	write_int_eeprom	d'45'
+	movff	temperature+1,EEDATA
+	write_int_eeprom	d'46'
+	return
+
+RTCinit:						; resets RTC 
+	movlw	0x80
+	movwf	TMR1H
+	clrf	TMR1L
+
+; Reset RTC if any part of the time/date is out of range
+	movlw	d'60'				; Limit
+	cpfslt	secs				; Check part
+	bra		RTCinit2			; Reset time...
+	movlw	d'60'				; Limit
+	cpfslt	mins				; Check part
+	bra		RTCinit2			; Reset time...
+	movlw	d'24'				; Limit
+	cpfslt	hours				; Check part
+	bra		RTCinit2			; Reset time...
+	movlw	d'32'				; Limit
+	cpfslt	day					; Check part
+	bra		RTCinit2			; Reset time...
+	movlw	d'12'				; Limit
+	cpfslt	month				; Check part
+	bra		RTCinit2			; Reset time...
+	movlw	d'100'				; Limit
+	cpfslt	year				; Check part
+	bra		RTCinit2			; Reset time...
+
+	bsf		PIE1, TMR1IE
+	return
+
+RTCinit2:
+	movlw	.00
+	movwf	secs
+	movlw	.00
+	movwf	mins
+	movlw	.12
+	movwf	hours
+	movlw	.2
+	movwf	day
+	movlw	.8
+	movwf	month
+	movlw	.09
+	movwf	year
+	bsf		PIE1, TMR1IE
+	return
\ No newline at end of file