Mercurial > public > hwos_code
diff src/calibrate.asm @ 604:ca4556fb60b9
bump to 2.99beta, work on 3.00 stable
author | heinrichsweikamp |
---|---|
date | Thu, 22 Nov 2018 19:47:26 +0100 |
parents | b455b31ce022 |
children | c40025d8e750 |
line wrap: on
line diff
--- a/src/calibrate.asm Thu Oct 11 21:06:29 2018 +0200 +++ b/src/calibrate.asm Thu Nov 22 19:47:26 2018 +0100 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File calibration.asm REFACTORED VERSION V2.98 +; File calibration.asm REFACTORED VERSION V2.98b ; ; o2 sensor calibration subroutines ; @@ -8,209 +8,180 @@ ;============================================================================= #include "hwos.inc" -#include "shared_definitions.h" ; Mailbox between c and asm +#include "shared_definitions.h" ; mailbox between c and asm #include "math.inc" #include "adc_lightsensor.inc" #include "eeprom_rs232.inc" +#include "isr.inc" calibrate CODE - global check_sensors ; Check O2 sensor thresholds for fallback and voting logic -check_sensors: - ; Check min_mv - 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 use_O2_sensor1 ;=1: Use this sensor for deco - btfsc neg_flag - bcf use_O2_sensor1 ;=1: Use this sensor for deco + + global transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics +transmit_setpoint: + return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!! + btfss s8_digital ; S8 Digital connection existing? + return ; NO - ignore + ; YES - transmit setpoint from WREG + clrf lo ; initialize checksum + movwf hi ; store setpoint + movlw 0xAA ; start byte + rcall tx_to_HUD ; transmit to HUD + movlw 0x60 ; command new SP + rcall tx_to_HUD ; transmit to HUD + movff hi,WREG ; SP in cbar + rcall tx_to_HUD ; transmit to HUD + movff lo,WREG ; checksum + rcall tx_to_HUD_cs ; transmit checksum + return + +tx_to_HUD: ; entry point to transmit a byte to the HUD + addwf lo,F ; add byte to checksum +tx_to_HUD_cs: ; entry point to transmit the checksum + movff WREG,TXREG2 ; transmit byte + call rs232_wait_tx2 ; wait for UART + return + - 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 use_O2_sensor2 ;=1: Use this sensor for deco - btfsc neg_flag - bcf use_O2_sensor2 ;=1: Use this sensor for deco + global calibrate_mix +calibrate_mix: + ; set usage and calibration flags as per default + bsf use_O2_sensor1 + bsf use_O2_sensor2 + bsf use_O2_sensor3 + bsf sensor1_calibrated_ok + bsf sensor2_calibrated_ok + bsf sensor3_calibrated_ok + + ; check for HUD + btfss s8_digital ; S8 Digital connection existing? + bra calibrate_mix1 ; NO - skip HUD part - 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 use_O2_sensor3 ;=1: Use this sensor for deco - btfsc neg_flag - bcf use_O2_sensor3 ;=1: Use this sensor for deco + ; calibrate any S8-connected HUD + clrf lo ; initialize checksum + movlw 0xAA ; start byte + rcall tx_to_HUD ; transmit to HUD + movlw 0x31 ; calibration command + rcall tx_to_HUD ; transmit to HUD + movff opt_calibration_O2_ratio,WREG ; calibration gas %O2 + rcall tx_to_HUD ; transmit to HUD + movff amb_pressure+0,WREG ; ambient pressure low byte + rcall tx_to_HUD ; transmit to HUD + movff amb_pressure+1,WREG ; ambient pressure high byte + rcall tx_to_HUD ; transmit to HUD + movff lo,WREG ; checksum + rcall tx_to_HUD_cs ; transmit to HUD +; bra calibrate_mix2 - ; Check max_mv - movff o2_mv_sensor1+0, sub_a+0 + ; calibrate internal sensors +calibrate_mix1: ; compute %O2 * 100 * ambient_pressure[mbar] / 100 + movff opt_calibration_O2_ratio,WREG + mullw .100 + movff PRODL,xA+0 + movff PRODH,xA+1 + SAFE_2BYTE_COPY amb_pressure,xB + 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 + + ; keep a copy of the result + movff xC+0,lo + movff xC+1,hi + movff xC+2,up + movff xC+3,ex + + ; compute factor for sensor 1 + 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 + movff xC+0,opt_x_s1+0 ; xC= ppO2/mV as factor for sensor 1 + movff xC+1,opt_x_s1+1 + + ; restore result + movff lo,xC+0 + movff hi,xC+1 + movff up,xC+2 + movff ex,xC+3 + + ; compute factor for sensor 2 + 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 + movff xC+0,opt_x_s2+0 ; xC= ppO2/mV as factor for sensor 2 + movff xC+1,opt_x_s2+1 + + ; restore result + movff lo,xC+0 + movff hi,xC+1 + movff up,xC+2 + movff ex,xC+3 + + ; compute factor for sensor 3 + 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 + movff xC+0,opt_x_s3+0 ; xC= ppO2/mV as factor for sensor 3 + movff xC+1,opt_x_s3+1 + + ; check sensor 1 for min/max mV + movff o2_mv_sensor1+0, sub_a+0 ; get mV from sensor 1 movff o2_mv_sensor1+1, sub_a+1 - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 - call sub16 ; sub_c = sub_a - sub_b - btfss neg_flag - bcf use_O2_sensor1 ;=1: Use this sensor for deco + rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 + TSTFSZ WREG ; sensor mV within thresholds? + bcf use_O2_sensor1 ; NO - clear usage flag - movff o2_mv_sensor2+0, sub_a+0 + ; check sensor 2 for min/max mV + movff o2_mv_sensor2+0, sub_a+0 ; get mV from sensor 2 movff o2_mv_sensor2+1, sub_a+1 - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 - call sub16 ; sub_c = sub_a - sub_b - btfss neg_flag - bcf use_O2_sensor2 ;=1: Use this sensor for deco + rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 + TSTFSZ WREG ; sensor mV within thresholds? + bcf use_O2_sensor2 ; NO - clear usage flag - movff o2_mv_sensor3+0, sub_a+0 + ; check sensor 3 for min/max mV + movff o2_mv_sensor3+0, sub_a+0 ; get mV from sensor 3 movff o2_mv_sensor3+1, sub_a+1 - movlw LOW max_mv - movwf sub_b+0 - movlw HIGH max_mv - movwf sub_b+1 - call sub16 ; sub_c = sub_a - sub_b - btfss neg_flag - bcf use_O2_sensor3 ;=1: Use this sensor for deco + rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 + TSTFSZ WREG ; sensor mV within thresholds? + bcf use_O2_sensor3 ; NO - clear usage flag - btfss hud_connection_ok ;=1: HUD connection ok - bra check_sensor2 ; No HUD/Digital data +calibrate_mix2: + ; check for HUD + btfss hud_connection_ok ; HUD connection existing? + bra calibrate_mix3 ; NO - skip HUD part - ; Copy disable flags from digital input + ; Copy disable flags from HUD digital input btfss sensor1_active bcf use_O2_sensor1 btfss sensor2_active bcf use_O2_sensor2 btfss sensor3_active bcf use_O2_sensor3 - return - -check_sensor2: - ; Copy disable flags from internal calibration routine - btfss sensor1_calibrated_ok - bcf use_O2_sensor1 - btfss sensor2_calibrated_ok - bcf use_O2_sensor2 - btfss sensor3_calibrated_ok - bcf use_O2_sensor3 - return - - - global calibrate_mix -calibrate_mix: - ; calibrate S8 HUD - btfss s8_digital ; S8 Digital? - bra calibrate_mix2 ; No - - ; Yes, calibrate any S8-connected HUD - clrf lo ; Checksum - movlw 0xAA ; Start Byte - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movlw 0x31 ; Calibrate - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movff amb_pressure+0,WREG ; Ambient pressure - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - movff amb_pressure+1,WREG - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movff lo,TXREG2 ; Checksum - 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 - rcall calibrate_mix2_helper - 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 +calibrate_mix3: + ; clear calibration flags if sensors are not found to be ok + btfss use_O2_sensor1 ; sensor 1 out of range? + bcf sensor1_calibrated_ok ; YES - disable this sensor + btfss use_O2_sensor2 ; sensor 2 out of range? + bcf sensor2_calibrated_ok ; YES - disable this sensor + btfss use_O2_sensor3 ; sensor 3 out of range? + bcf sensor3_calibrated_ok ; YES - disable this sensor - 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 - rcall calibrate_mix2_helper - 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 - rcall calibrate_mix2_helper - 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 - - bsf sensor1_calibrated_ok - bsf sensor2_calibrated_ok - bsf sensor3_calibrated_ok ; Set flags prior check - - rcall check_sensors ; Check O2 sensor thresholds min_mv and max_mv and set use_02_sensorX flags - ; initialize internal calibration flags - btfss use_O2_sensor1 ; Sensor out of range? - bcf sensor1_calibrated_ok ; Yes, disable this sensor - btfss use_O2_sensor2 ; Sensor out of range? - bcf sensor2_calibrated_ok ; Yes, disable this sensor - btfss use_O2_sensor3 ; Sensor out of range? - bcf sensor3_calibrated_ok ; Yes, disable this sensor - - ; When no sensor is found, enable all three to show error state + ; When no sensor is found, enable all three to show error state and clear calibration factors btfsc use_O2_sensor1 return btfsc use_O2_sensor2 return btfsc use_O2_sensor3 return + ; Enable all sensors bsf use_O2_sensor1 bsf use_O2_sensor2 bsf use_O2_sensor3 - ; Clear factors + ; Clear calibration factors banksel opt_x_s1+0 clrf opt_x_s1+0 clrf opt_x_s1+1 @@ -221,90 +192,60 @@ banksel common return - -calibrate_mix2_helper: - call mult16x16 ; xA*xB=xC - movlw LOW .100 - movwf xB+0 - movlw HIGH .100 - movwf xB+1 - goto div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder (And return) +calibrate_mix_helper: + movlw LOW min_mv ; load minimum threshold... + movwf sub_b+0 ; ...into sub_b + movlw HIGH min_mv + movwf sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; sensor mV lower than minimum threshold? + retlw .1 ; YES - return signaling threshold violation + movlw LOW max_mv ; load maximum threshold... + movwf sub_b+0 ; ...into sub_b + movlw HIGH max_mv + movwf sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + btfss neg_flag ; sensor mV higher than maximum threshold? + retlw .1 ; YES - return signaling threshold violation + retlw .0 ; NO - return signaling min/max ok global compute_mvolts_for_all_sensors -compute_mvolts_for_all_sensors: ; Compute mV or all sensors (S8 Mode) +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 ; Divide 24bit value through 409,5999512 -> 410 (0,01% error) #DEFINE ad2mv_factor .410 + movlw LOW ad2mv_factor + movwf xB+0 + movlw HIGH ad2mv_factor + movwf xB+1 ; Sensor 1 clrf xC+3 movff s8_rawdata_sensor1+2,xC+2 movff s8_rawdata_sensor1+1,xC+1 movff s8_rawdata_sensor1+0,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 + movff xC+0,o2_mv_sensor1+0 ; in 100 uV steps ; Sensor 2 clrf xC+3 movff s8_rawdata_sensor2+2,xC+2 movff s8_rawdata_sensor2+1,xC+1 movff s8_rawdata_sensor2+0,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 + movff xC+0,o2_mv_sensor2+0 ; in 100 uV steps ; Sensor 3 clrf xC+3 movff s8_rawdata_sensor3+2,xC+2 movff s8_rawdata_sensor3+1,xC+1 movff s8_rawdata_sensor3+0,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. - - - global transmit_setpoint ; Transmit current setpoint from WREG (in cbar) to external electronics -transmit_setpoint: - return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!! - btfss s8_digital ; S8 Digital? - return ; No, ignore + movff xC+0,o2_mv_sensor3+0 ; in 100 uV steps - ; Yes, transmit setpoint from WREG - movwf hi ; Store setpoint - clrf lo ; Checksum - movlw 0xAA ; Start Byte - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movlw 0x60 ; New SP - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movff hi,WREG ; SP in cbar - addwf lo,F - movff WREG,TXREG2 - call rs232_wait_tx2 - - movff lo,TXREG2 ; Checksum - call rs232_wait_tx2 - return - + bcf new_s8_data_available ; clear flag + return ; done END \ No newline at end of file