diff src/ms5541.asm @ 646:5b7fe7777425

3.16 release
author heinrichs weikamp
date Thu, 14 Oct 2021 12:03:24 +0200
parents 4050675965ea
children 357341239438
line wrap: on
line diff
--- a/src/ms5541.asm	Thu Jan 14 16:24:07 2021 +0100
+++ b/src/ms5541.asm	Thu Oct 14 12:03:24 2021 +0200
@@ -11,7 +11,8 @@
 
 #include "hwos.inc"						; Mandatory header
 #include "math.inc"						; Math routines
-
+#include "i2c.inc"
+#include "shared_definitions.h"				; mailbox from/to p2_deco.c
 
 ms5541	CODE
 
@@ -31,6 +32,9 @@
 calculate_compensation:
 	banksel	isr_backup					; select bank ISR data
 
+	btfsc	press_sensor_type			; New sensor found?
+	bra 	press_comp_ms5837			; Yes, use MS5837
+
 	;---- pressure sensor compensation
 
 	; xdT = D2 - C5 (s16 range -11.400 .. +12.350)
@@ -131,7 +135,7 @@
 
 	MOVII	SENS,isr_xB					; sens --> B
 	call	isr_signed_mult16x16		; C = A*B
-	movlw	.13							; 12 * 256 = 3328
+	movlw	.15							; 15 * 256 = 3840
 	cpfslt	C1+1						; C1 > 3328 ?
 	bra		isr_shift_ms5541_30			; YES - MS5541-30
 	movlw	.12-.8						; NO  - MS5541: 12 bit shift = 1 byte + 4 bits
@@ -144,7 +148,144 @@
 	addwf	isr_xC+1,F					; ...
 	movlw	HIGH .1000					; ...
 	addwfc	isr_xC+2,F					; ...
+	bra	press_comp_done_common
 
+press_comp_ms5837:
+ 	; xdT = D2 - C5*2^8
+	movlw	.0		; Low
+	subwf	D2+0,W
+	movwf	xdT+0
+	movf	C5+0,W		; High
+	subwfb	D2+1,W
+	movwf	xdT+1
+	movf	C5+1,W		; Upper
+	subwfb	D2+2,W
+	movwf	xdT+2
+	; xdT equals D2 - (C5*2^8)
+	
+	; Calculate OFF = C2*2^16+(C4*xdT)/2^7
+	movff	C4+0,isr_xA+0
+	movff	C4+1,isr_xA+1
+	clrf	isr_xA+2
+	movff	xdT+0,isr_xB+0
+	movff	xdT+1,isr_xB+1
+	movff	xdT+2,isr_xB+2
+	call	isr_signed_mult24x24		; C = A*B
+	; isr_xC:6 equals (C4*xdT)
+	rlcf	isr_xC+0,F
+	rlcf	isr_xC+1,F
+	rlcf	isr_xC+2,F
+	rlcf	isr_xC+3,F
+	rlcf	isr_xC+4,F
+	rlcf	isr_xC+5,F
+	movff	isr_xC+1,OFF+0
+	movff	isr_xC+2,OFF+1
+	movff	isr_xC+3,OFF+2
+	movff	isr_xC+4,OFF+3
+	; OFF equals (C4*xdT)/2^7
+	movf	C2+0,W
+	addwf	OFF+2,F
+	movf	C2+1,W
+	addwfc	OFF+3,F
+	; OFF equals C2*2^16+((C4*xdT)/2^7)
+	
+	; Calculate SENS = C1*2^15 + (C3*xdT)/2^8
+	MOVII	C1,isr_xA
+	movlw	LOW	(.32768)
+	movwf	isr_xB+0
+	movlw	HIGH	(.32768)
+	movwf	isr_xB+1
+	call	isr_unsigned_mult16x16		; C = A*B
+	movff	isr_xC+0,SENS+0
+	movff	isr_xC+1,SENS+1
+	movff	isr_xC+2,SENS+2
+	movff	isr_xC+3,SENS+3			; 32bit copy
+	; SENS equals C1*2^15
+	movff	C3+0,isr_xA+0
+	movff	C3+1,isr_xA+1
+	clrf	isr_xA+2
+	movff	xdT+0,isr_xB+0
+	movff	xdT+1,isr_xB+1
+	movff	xdT+2,isr_xB+2
+	call	isr_signed_mult24x24		; C = A*B
+	; isr_xC:6 equals (C3*xdT)
+	movf	isr_xC+1,W
+	addwf	SENS+0,F
+	movf	isr_xC+2,W
+	addwfc	SENS+1,F
+	movf	isr_xC+3,W
+	addwfc	SENS+2,F
+	movf	isr_xC+4,W
+	addwfc	SENS+3,F
+	; SENS equals C1*2^15 + (C3*xdT)/2^8
+
+	; Calculate PRESSURE = ((D1 * SENS) / 2^21) - OFF) / 2^13
+	movff	SENS+0,isr_xA+0
+	movff	SENS+1,isr_xA+1
+	movff	SENS+2,isr_xA+2
+	movff	SENS+3,isr_xA+3
+	movff	D1+0,isr_xB+0
+	movff	D1+1,isr_xB+1
+	movff	D1+2,isr_xB+2
+	call	isr_unsigned_mult32x24		; C = A*B
+	; isr_xC:7 equals D1*SENS
+
+	; devide isr_xC:7 / 2^21 -> shift right 21 times
+	movlw	.21
+press_comp_ms5837_2:
+	bcf	STATUS,C					; clear carry, needed for MS5837 use
+	rrcf	isr_xC+6,F
+	rrcf	isr_xC+5,F
+	rrcf	isr_xC+4,F
+	rrcf	isr_xC+3,F
+	rrcf	isr_xC+2,F
+	rrcf	isr_xC+1,F
+	rrcf	isr_xC+0,F
+	decfsz	WREG						; decrement loop counter, done?
+	bra	press_comp_ms5837_2			; NO  - loop		
+	; isr_xC:6 equals (D1*SENS)/2^21
+	
+	; Calculate isr_xC:6-OFF
+	movf	OFF+0,W	    ; Low
+	subwf	isr_xC+0,F
+	movf	OFF+1,W	    ; High
+	subwfb	isr_xC+1,F
+	movf	OFF+2,W	    ; Upper
+	subwfb	isr_xC+2,F
+	movf	OFF+3,W	    ; Extra
+	subwfb	isr_xC+3,F
+	movlw	.0	    ; ultra
+	subwfb	isr_xC+4,F
+	movlw	.0	    ; Hyper
+	subwfb	isr_xC+5,F
+	; isr_xC:5 is now isr_xC:4-OFF
+	
+	; devide by 2^13
+	; devide isr_xC:6 / 2^13 -> shift right 13 times
+	movlw	.13
+press_comp_ms5837_3:
+	bcf	STATUS,C					; clear carry
+	rrcf	isr_xC+5,F
+	rrcf	isr_xC+4,F
+	rrcf	isr_xC+3,F
+	rrcf	isr_xC+2,F
+	rrcf	isr_xC+1,F
+	rrcf	isr_xC+0,F
+	decfsz	WREG						; decrement loop counter, done?
+	bra	press_comp_ms5837_3			; NO  - loop		
+	; isr_xC:4 equals pressure in .1 mbar
+
+	movlw	.10
+	movwf	isr_xB+0
+	clrf	isr_xB+1
+	call	isr_div32x16				; isr_xC:4 = isr_xC:4 / isr_xB:2 with isr_xA as remainder
+	; isr_xC:2 equals pressure in 1mbar
+
+	; copy for compatibility of the next routines
+	movff	isr_xC+1,isr_xC+2
+	movff	isr_xC+0,isr_xC+1
+	
+press_comp_done_common:						; continue here even with MS5837
 	; add opt_pressure_adjust to result (SIGNED!)
 	clrf	isr_xC+0					; prepare high byte for adjustment
 	movff	opt_pressure_adjust,WREG	; get     low  byte for adjustment (signed)
@@ -256,9 +397,14 @@
 	addwf	pressure_abs_avg+0,F		; pressure_abs_avg += current pressure,   low  byte
 	movf	isr_xC+2,W					; copy current absolute pressure to WREG, high byte
 	addwfc	pressure_abs_avg+1,F		; pressure_abs_avg += current pressure,   high byte
+	movlw	.0
+	addwfc	pressure_abs_avg+2,F		; pressure_abs_avg += current pressure,   upper byte
 
 	;---- temperature sensor compensation
 
+    	btfsc	press_sensor_type			; New sensor found?
+	bra	temp_comp_ms5837			; Yes, use MS5837
+	
 	; calculate temp = 200 + dT*(C6+100)/2^11
 	movlw	LOW(.100)					; C6 + 100 --> A
 	addwf	C6+0,W						; ...
@@ -276,7 +422,71 @@
 	addwf	isr_xC+1,F					; ...
 	movlw	HIGH(.200)					; ...
 	addwfc	isr_xC+2,F					; ...
+	bra	temp_comp_done_common
 
+temp_comp_ms5837:
+    	; TEMP = 2000+((xdT * C6) / 2^23)
+	
+	; xdT * C6 -> isr_xC:6
+	movff	C6+0,isr_xA+0
+	movff	C6+1,isr_xA+1
+	clrf	isr_xA+2
+	movff	xdT+0,isr_xB+0
+	movff	xdT+1,isr_xB+1
+	movff	xdT+2,isr_xB+2
+	call	isr_signed_mult24x24		; A*B
+	
+	; devide isr_xC:6 / 2^23 -> shift right 23 times
+	; a special variant (again): We loose isr_xC+0 and isr_xC+1 anyway 
+	; and do not care about the inserted carry since we won't use isr_xC+5 
+	; and we shift less then 8 bytes
+	movlw	.23-.16	    
+temp_comp_ms5837_2:
+	rrcf	isr_xC+5,F					; 
+        rrcf	isr_xC+4,F					; 
+	rrcf	isr_xC+3,F					; 
+	rrcf	isr_xC+2,F					; ...
+	decfsz	WREG						; decrement loop counter, done?
+	bra	temp_comp_ms5837_2			; NO  - loop	
+
+	; only use +2 and +3
+	movlw	LOW(.2000)					; add 2000
+	addwf	isr_xC+2,F					; ...
+	movlw	HIGH(.2000)					; ...
+	addwfc	isr_xC+3,F					; ...
+
+	; devide by 10 for .1°C resolution
+	movlw	.10
+	movwf	isr_xB+0
+	clrf	isr_xB+1
+	movff	isr_xC+2,isr_xA+0
+	movff	isr_xC+3,isr_xA+1
+
+	btfss	isr_xC+3,7		    ; check sign bit
+	bra	temp_comp_ms5837_3	    ; not negative...
+	; negate isr_xA:2 to make it positive
+	comf	isr_xA+1		    ; 16 bit sign change
+	negf	isr_xA+0
+	btfsc	STATUS,C		    ; - carry to propagate?
+	incf	isr_xA+1,F		    ;  YES - do it
+
+temp_comp_ms5837_3:
+	call	isr_div16x16					; isr_xC:2 = isr_xA:2 / isr_xB:2
+
+	btfss	isr_xC+3,7		    ; check sign bit again
+	bra	temp_comp_ms5837_4	    ; not negative...
+	; negate result isr_xC:2 to make it negative again
+	comf	isr_xC+1		    ; 16 bit sign change
+	negf	isr_xC+0
+	btfsc	STATUS,C		    ;- carry to propagate?
+	incf	isr_xC+1,F		    ; YES - do it
+	
+temp_comp_ms5837_4:	
+	; copy for compatibility of the next routines
+	movff	isr_xC+1,isr_xC+2
+	movff	isr_xC+0,isr_xC+1
+	
+temp_comp_done_common:						; continue here even with MS5837	
 	; add opt_temperature_adjust to result (SIGNED!)
 	clrf	isr_xC+0					; prepare high byte for adjustment
 	movff	opt_temperature_adjust,WREG	; get     low  byte for adjustment (signed)
@@ -309,12 +519,13 @@
 ;
 	global	get_pressure_start
 get_pressure_start:
+       	btfsc	press_sensor_type			; New sensor found?
+	return						; Yes, ignore routine
 	rcall	reset_MS5541				; reset the chip
 	movlw	b'10100000'					; +3*high as start and 1+low as stop
 	movwf	dbuffer						; ....
 	movlw	d'12'						; send start command
-	rcall	send_data_MS5541			; ...
-	return								; done
+	bra 	send_data_MS5541				; ... (And return)
 
 
 ;-----------------------------------------------------------------------------
@@ -324,6 +535,8 @@
 ;
 	global get_pressure_value
 get_pressure_value:
+       	btfsc	press_sensor_type			; New sensor found?
+	bra	get_pressure_value2
 	btfsc	MS5541_miso					; conversion done?
 	return								; NO  - abort
 	rcall	get_2bytes_MS5541			; YES - read result
@@ -331,6 +544,14 @@
 	movff	dLSB,D1+0					; ...                low  byte second
 	return								; done
 
+get_pressure_value2:	
+	btfsc	i2c_busy_pressure			; currently updating pressure?
+	return						; Yes, skip update...
+	movff	D1_buffer+0,D1+0
+	movff	D1_buffer+1,D1+1
+	movff	D1_buffer+2,D1+2
+	return
+	
 
 ;-----------------------------------------------------------------------------
 ; Start Temperature Measurement
@@ -339,12 +560,13 @@
 ;
 	global	get_temperature_start
 get_temperature_start:
+       	btfsc	press_sensor_type			; New sensor found?
+	return						; Yes, ignore routine
 	rcall	reset_MS5541				; reset chip
 	movlw	b'10010000'					; +3*high as start and 1+low as stop
 	movwf	dbuffer						; ...
 	movlw	d'12'						; send start command
-	rcall	send_data_MS5541			; ...
-	return								; done
+	bra	send_data_MS5541				; ... (And return)
 
 
 ;-----------------------------------------------------------------------------
@@ -354,6 +576,8 @@
 ;
 	global	get_temperature_value
 get_temperature_value:
+	btfsc	press_sensor_type			; New sensor found?
+	bra	get_temperature_value2
 	btfsc	MS5541_miso					; conversion done?
 	return								; NO - done
 	rcall	get_2bytes_MS5541			; YES - read result
@@ -361,6 +585,14 @@
 	movff	dLSB,D2+0					; ...                low  byte second
 	return								; done
 
+get_temperature_value2:
+	btfsc	i2c_busy_temperature			; currently updating temperature?
+	return						; Yes, skip update...
+	movff	D2_buffer+0,D2+0
+	movff	D2_buffer+1,D2+1
+	movff	D2_buffer+2,D2+2
+	return
+	
 
 ;-----------------------------------------------------------------------------
 ; Retrieve Calibration Data
@@ -370,8 +602,32 @@
 	global	get_calibration_data
 get_calibration_data:
 	banksel	isr_backup					; select bank ISR data
-	bsf		block_sensor_interrupt		; disable sensor interrupts
+	bsf	    block_sensor_interrupt		; disable sensor interrupts
 
+	btfsc	press_sensor_type			; New sensor found?
+	call	I2C_get_calib_MS5837			; Yes, read C1 to C6
+	banksel	isr_backup					; select bank ISR data
+	; double-check sensor type
+	movlw	0xED
+	cpfseq	C1+0
+	bra	get_calibration_data1			; Not 0xED (I2C address false reading)
+	movlw	0xED
+	cpfseq	C1+1
+	bra	get_calibration_data1			; Not 0xED (I2C address false reading)
+	movlw	0xED
+	cpfseq	C5+0
+	bra	get_calibration_data1			; Not 0xED (I2C address false reading)
+	movlw	0xED
+	cpfseq	C5+1
+	bra	get_calibration_data1			; Not 0xED (I2C address false reading)
+	
+	; C1 and C5 are 0xEDED -> NOT Sensor 1
+	bcf	press_sensor_type
+	
+get_calibration_data1:	
+	btfsc	press_sensor_type			; New sensor found?
+	bra	get_calibration_data2			; Yes, skip to the end
+	
 	rcall	reset_MS5541				; reset chip
 
 	movlw	b'01010100'					; +3*high as start and 1+low as stop
@@ -545,6 +801,7 @@
 	movff	ir_s8_buffer+6,C6+0
 	bcf		C6+0,7
 
+get_calibration_data2:
 	clrf	sensor_state_counter		; reset state counter
 	bcf		block_sensor_interrupt		; re-enable sensor interrupts
 	banksel	common						; back to bank common