Mercurial > public > hwos_code
diff src/calibrate.asm @ 113:f3062a611eef
Merge
author | heinrichsweikamp |
---|---|
date | Mon, 23 Jun 2014 16:14:33 +0200 |
parents | |
children | e3ac5b2021bc |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/calibrate.asm Mon Jun 23 16:14:33 2014 +0200 @@ -0,0 +1,307 @@ +;============================================================================= +; +; File calibration.asm +; +; o2 sensor calibration subroutines +; +; Copyright (c) 2014, Heinrichs Weikamp, all right reserved. +;============================================================================= + +#include "ostc3.inc" +#include "shared_definitions.h" ; Mailbox between c and asm +#include "math.inc" +#include "adc_lightsensor.inc" +#include "eeprom_rs232.inc" + +calibrate CODE + + global calibrate_mix +calibrate_mix: + ; calibrate S8 HUD + btfss s8_digital ; S8 Digital? + bra calibrate_mix2 ; No + + clrf temp1 ; Chksum + movlw 0xAA ; Start Byte + addwf temp1,F + movff WREG,TXREG2 + call rs232_wait_tx2 + + movlw 0x31 ; Calibrate + addwf temp1,F + movff WREG,TXREG2 + call rs232_wait_tx2 + + movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 + addwf temp1,F + movff WREG,TXREG2 + call rs232_wait_tx2 + + movff amb_pressure+0,WREG ; Ambient pressure + addwf temp1,F + movff WREG,TXREG2 + call rs232_wait_tx2 + movff amb_pressure+1,WREG + addwf temp1,F + movff WREG,TXREG2 + call rs232_wait_tx2 + + movff temp1,TXREG2 ; Chksum + call rs232_wait_tx2 + +calibrate_mix2: + movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 + mullw .100 + movff PRODL,xA+0 + movff PRODH,xA+1 +; (%O2*100)*[ambient,mbar]/100 -> xC + movff amb_pressure+0,xB+0 + movff amb_pressure+1,xB+1 + call mult16x16 ;xA*xB=xC + movlw LOW .100 + movwf xB+0 + movlw HIGH .100 + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff o2_mv_sensor1+0,xB+0 + movff o2_mv_sensor1+1,xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + ; xC= ppO2/mV + movff xC+0,opt_x_s1+0 + movff xC+1,opt_x_s1+1 ; Factor for Sensor1 + + movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 + mullw .100 + movff PRODL,xA+0 + movff PRODH,xA+1 +; (%O2*100)*[ambient,mbar]/100 -> xC + movff amb_pressure+0,xB+0 + movff amb_pressure+1,xB+1 + call mult16x16 ;xA*xB=xC + movlw LOW .100 + movwf xB+0 + movlw HIGH .100 + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff o2_mv_sensor2+0,xB+0 + movff o2_mv_sensor2+1,xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + ; xC= ppO2/mV + movff xC+0,opt_x_s2+0 + movff xC+1,opt_x_s2+1 ; Factor for Sensor2 + + movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 + mullw .100 + movff PRODL,xA+0 + movff PRODH,xA+1 +; (%O2*100)*[ambient,mbar]/100 -> xC + movff amb_pressure+0,xB+0 + movff amb_pressure+1,xB+1 + call mult16x16 ;xA*xB=xC + movlw LOW .100 + movwf xB+0 + movlw HIGH .100 + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff o2_mv_sensor3+0,xB+0 + movff o2_mv_sensor3+1,xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + ; xC= ppO2/mV + movff xC+0,opt_x_s3+0 + movff xC+1,opt_x_s3+1 ; Factor for Sensor3 + + ; Result is in 100µV + movff o2_mv_sensor1+0, sub_a+0 + movff o2_mv_sensor1+1, sub_a+1 + movlw LOW min_mv + movwf sub_b+0 + movlw HIGH min_mv + movwf sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + bsf sensor1_active ; Sensor active! + btfsc neg_flag + bcf sensor1_active + + ; Result is in 100µV + movff o2_mv_sensor2+0, sub_a+0 + movff o2_mv_sensor2+1, sub_a+1 + movlw LOW min_mv + movwf sub_b+0 + movlw HIGH min_mv + movwf sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + bsf sensor2_active ; Sensor active! + btfsc neg_flag + bcf sensor2_active + + ; Result is in 100µV + movff o2_mv_sensor3+0, sub_a+0 + movff o2_mv_sensor3+1, sub_a+1 + movlw LOW min_mv + movwf sub_b+0 + movlw HIGH min_mv + movwf sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + bsf sensor3_active ; Sensor active! + btfsc neg_flag + bcf sensor3_active + + ; When no sensor is found, enable all three to show error state + btfsc sensor1_active + return + btfsc sensor2_active + return + btfsc sensor3_active + return + bsf sensor1_active + bsf sensor2_active + bsf sensor3_active + ; Clear factors + banksel opt_x_s1+0 + clrf opt_x_s1+0 + clrf opt_x_s1+1 + clrf opt_x_s2+0 + clrf opt_x_s2+1 + clrf opt_x_s3+0 + clrf opt_x_s3+1 + banksel common + return + +compute_ppo2_analog: + call get_analog_inputs + bra compute_ppo2_common + + global compute_ppo2 ; compute mv_sensorX and ppo2_sensorX arrays +compute_ppo2: + btfss c3_hardware ; C3 hardware? + return ; No + + btfss s8_digital ; =1: Digital I/O + bra compute_ppo2_analog ; use analog + + ; use digital + btfss new_s8_data_available ; =1: New data frame recieved + return + call compute_mvolts_for_all_sensors + +compute_ppo2_common: + ; o2_mv_sensor1:2 * opt_x_s1:2 = o2_ppo2_sensor1/10000 + movff o2_mv_sensor1+0,xA+0 + movff o2_mv_sensor1+1,xA+1 + movff opt_x_s1+0,xB+0 + movff opt_x_s1+1,xB+1 + call mult16x16 ;xA:2*xB:2=xC:4 + movlw LOW .1000 + movwf xB+0 + movlw HIGH .1000 + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movlw d'1' + addwf xC+0,F + movlw d'0' + addwfc xC+1,F + movff xC+0,o2_ppo2_sensor1+0 + movff xC+1,o2_ppo2_sensor1+1 ; result in 0.01bar + ; Set to zero if sensor is not active! + btfss sensor1_active + clrf o2_ppo2_sensor1+0 + btfss sensor1_active + clrf o2_ppo2_sensor1+1 + + ; o2_mv_sensor2:2 * opt_x_s1:2 = o2_ppo2_sensor2/10000 + movff o2_mv_sensor2+0,xA+0 + movff o2_mv_sensor2+1,xA+1 + movff opt_x_s2+0,xB+0 + movff opt_x_s2+1,xB+1 + call mult16x16 ;xA:2*xB:2=xC:4 + movlw LOW .1000 + movwf xB+0 + movlw HIGH .1000 + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movlw d'1' + addwf xC+0,F + movlw d'0' + addwfc xC+1,F + movff xC+0,o2_ppo2_sensor2+0 + movff xC+1,o2_ppo2_sensor2+1 ; result in 0.01bar + ; Set to zero if sensor is not active! + btfss sensor2_active + clrf o2_ppo2_sensor2+0 + btfss sensor2_active + clrf o2_ppo2_sensor2+1 + + ; o2_mv_sensor3:2 * opt_x_s1:2 = o2_ppo2_sensor3/10000 + movff o2_mv_sensor3+0,xA+0 + movff o2_mv_sensor3+1,xA+1 + movff opt_x_s3+0,xB+0 + movff opt_x_s3+1,xB+1 + call mult16x16 ;xA:2*xB:2=xC:4 + movlw LOW .1000 + movwf xB+0 + movlw HIGH .1000 + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movlw d'1' + addwf xC+0,F + movlw d'0' + addwfc xC+1,F + movff xC+0,o2_ppo2_sensor3+0 + movff xC+1,o2_ppo2_sensor3+1 ; result in 0.01bar + ; Set to zero if sensor is not active! + btfss sensor3_active + clrf o2_ppo2_sensor3+0 + btfss sensor3_active + clrf o2_ppo2_sensor3+1 + + return ; Done. + + +compute_mvolts_for_all_sensors: ; Compute mV or all sensors (S8 Mode) +; compute AD results in 100µV steps (16bit/sensor) +; 24bit AD result is in 244,1406541nV +; Devide 24bit value through 409,5999512 -> 410 (0,01% error) + #DEFINE ad2mv_factor .410 + ; Sensor 1 + clrf xC+3 + movff ir_buffer+.6,xC+2 + movff ir_buffer+.5,xC+1 + movff ir_buffer+.4,xC+0 + movlw LOW ad2mv_factor + movwf xB+0 + movlw HIGH ad2mv_factor + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff xC+1,o2_mv_sensor1+1 + movff xC+0,o2_mv_sensor1+0 ; in 100uV steps + ; Sensor 2 + clrf xC+3 + movff ir_buffer+.9,xC+2 + movff ir_buffer+.8,xC+1 + movff ir_buffer+.7,xC+0 + movlw LOW ad2mv_factor + movwf xB+0 + movlw HIGH ad2mv_factor + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff xC+1,o2_mv_sensor2+1 + movff xC+0,o2_mv_sensor2+0 ; in 100uV steps + ; Sensor 3 + clrf xC+3 + movff ir_buffer+.12,xC+2 + movff ir_buffer+.11,xC+1 + movff ir_buffer+.10,xC+0 + movlw LOW ad2mv_factor + movwf xB+0 + movlw HIGH ad2mv_factor + movwf xB+1 + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff xC+1,o2_mv_sensor3+1 + movff xC+0,o2_mv_sensor3+0 ; in 100uV steps + + bcf new_s8_data_available ; Clear flag + return ; Done. + + + + END \ No newline at end of file