Mercurial > public > hwos_code
comparison src/calibrate.asm @ 623:c40025d8e750
3.03 beta released
| author | heinrichsweikamp |
|---|---|
| date | Mon, 03 Jun 2019 14:01:48 +0200 |
| parents | ca4556fb60b9 |
| children | 185ba2f91f59 |
comparison
equal
deleted
inserted
replaced
| 622:02d1386429a6 | 623:c40025d8e750 |
|---|---|
| 1 ;============================================================================= | 1 ;============================================================================= |
| 2 ; | 2 ; |
| 3 ; File calibration.asm REFACTORED VERSION V2.98b | 3 ; File calibration.asm combined next generation V3.03.1 |
| 4 ; | 4 ; |
| 5 ; o2 sensor calibration subroutines | 5 ; o2 sensor calibration subroutines |
| 6 ; | 6 ; |
| 7 ; Copyright (c) 2014, Heinrichs Weikamp, all right reserved. | 7 ; Copyright (c) 2014, Heinrichs Weikamp, all right reserved. |
| 8 ;============================================================================= | 8 ;============================================================================= |
| 10 #include "hwos.inc" | 10 #include "hwos.inc" |
| 11 #include "shared_definitions.h" ; mailbox between c and asm | 11 #include "shared_definitions.h" ; mailbox between c and asm |
| 12 #include "math.inc" | 12 #include "math.inc" |
| 13 #include "adc_lightsensor.inc" | 13 #include "adc_lightsensor.inc" |
| 14 #include "eeprom_rs232.inc" | 14 #include "eeprom_rs232.inc" |
| 15 #include "isr.inc" | |
| 16 | 15 |
| 17 | 16 |
| 18 calibrate CODE | 17 calibrate CODE |
| 19 | 18 |
| 19 ;============================================================================= | |
| 20 | |
| 21 IFDEF _external_sensor | |
| 20 | 22 |
| 21 global transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics | 23 global transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics |
| 22 transmit_setpoint: | 24 transmit_setpoint: |
| 23 return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!! | 25 return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!! |
| 24 btfss s8_digital ; S8 Digital connection existing? | 26 btfss s8_digital_avail ; do we have a digital S8 interface? |
| 25 return ; NO - ignore | 27 return ; NO - ignore |
| 26 ; YES - transmit setpoint from WREG | 28 ; YES - transmit setpoint from WREG |
| 27 clrf lo ; initialize checksum | 29 clrf lo ; initialize checksum |
| 28 movwf hi ; store setpoint | 30 movff char_I_const_ppO2,hi ; copy setpoint value to hi |
| 29 movlw 0xAA ; start byte | 31 movlw 0xAA ; start byte |
| 30 rcall tx_to_HUD ; transmit to HUD | 32 rcall tx_to_HUD ; transmit to HUD |
| 31 movlw 0x60 ; command new SP | 33 movlw 0x60 ; command new SP |
| 32 rcall tx_to_HUD ; transmit to HUD | 34 rcall tx_to_HUD ; transmit to HUD |
| 33 movff hi,WREG ; SP in cbar | 35 movff hi,WREG ; SP in cbar |
| 52 bsf use_O2_sensor3 | 54 bsf use_O2_sensor3 |
| 53 bsf sensor1_calibrated_ok | 55 bsf sensor1_calibrated_ok |
| 54 bsf sensor2_calibrated_ok | 56 bsf sensor2_calibrated_ok |
| 55 bsf sensor3_calibrated_ok | 57 bsf sensor3_calibrated_ok |
| 56 | 58 |
| 59 ; ISR-safe 2 byte copy of the current pressure to xB for later use | |
| 60 SMOVII pressure_abs,xB | |
| 61 | |
| 57 ; check for HUD | 62 ; check for HUD |
| 58 btfss s8_digital ; S8 Digital connection existing? | 63 btfss s8_digital_avail ; do we have a digital S8 interface? |
| 59 bra calibrate_mix1 ; NO - skip HUD part | 64 bra calibrate_mix1 ; NO - skip HUD part |
| 60 | 65 |
| 61 ; calibrate any S8-connected HUD | 66 ; calibrate any S8-connected HUD |
| 62 clrf lo ; initialize checksum | 67 clrf lo ; initialize checksum |
| 63 movlw 0xAA ; start byte | 68 movlw 0xAA ; start byte |
| 64 rcall tx_to_HUD ; transmit to HUD | 69 rcall tx_to_HUD ; transmit to HUD |
| 65 movlw 0x31 ; calibration command | 70 movlw 0x31 ; calibration command |
| 66 rcall tx_to_HUD ; transmit to HUD | 71 rcall tx_to_HUD ; transmit to HUD |
| 67 movff opt_calibration_O2_ratio,WREG ; calibration gas %O2 | 72 movff opt_calibration_O2_ratio,WREG ; calibration gas %O2 |
| 68 rcall tx_to_HUD ; transmit to HUD | 73 rcall tx_to_HUD ; transmit to HUD |
| 69 movff amb_pressure+0,WREG ; ambient pressure low byte | 74 movff xB+0,WREG ; current absolute pressure low byte |
| 70 rcall tx_to_HUD ; transmit to HUD | 75 rcall tx_to_HUD ; transmit to HUD |
| 71 movff amb_pressure+1,WREG ; ambient pressure high byte | 76 movff xB+1,WREG ; current absolute pressure high byte |
| 72 rcall tx_to_HUD ; transmit to HUD | 77 rcall tx_to_HUD ; transmit to HUD |
| 73 movff lo,WREG ; checksum | 78 movff lo,WREG ; checksum |
| 74 rcall tx_to_HUD_cs ; transmit to HUD | 79 rcall tx_to_HUD_cs ; transmit to HUD |
| 75 ; bra calibrate_mix2 | 80 ; bra calibrate_mix2 |
| 76 | 81 |
| 77 ; calibrate internal sensors | 82 ; calibrate internal sensors |
| 78 calibrate_mix1: ; compute %O2 * 100 * ambient_pressure[mbar] / 100 | 83 calibrate_mix1: ; compute %O2 * 100 * absolute pressure [mbar] / 100 |
| 79 movff opt_calibration_O2_ratio,WREG | 84 movff opt_calibration_O2_ratio,WREG |
| 80 mullw .100 | 85 mullw .100 |
| 81 movff PRODL,xA+0 | 86 MOVII PROD,xA |
| 82 movff PRODH,xA+1 | |
| 83 SAFE_2BYTE_COPY amb_pressure,xB | |
| 84 call mult16x16 ; xA*xB=xC | 87 call mult16x16 ; xA*xB=xC |
| 85 movlw LOW .100 | 88 MOVLI .100,xB |
| 86 movwf xB+0 | 89 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 87 movlw HIGH .100 | |
| 88 movwf xB+1 | |
| 89 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 90 | 90 |
| 91 ; keep a copy of the result | 91 ; keep a copy of the result |
| 92 movff xC+0,lo | 92 movff xC+0,mpr+0 |
| 93 movff xC+1,hi | 93 movff xC+1,mpr+1 |
| 94 movff xC+2,up | 94 movff xC+2,mpr+2 |
| 95 movff xC+3,ex | 95 movff xC+3,mpr+3 |
| 96 | 96 |
| 97 ; compute factor for sensor 1 | 97 ; compute factor for sensor 1 |
| 98 movff o2_mv_sensor1+0,xB+0 | 98 MOVII sensor1_mv,xB |
| 99 movff o2_mv_sensor1+1,xB+1 | 99 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 100 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | 100 MOVII xC,opt_x_s1 ; xC = ppO2/mV as factor for sensor 1 |
| 101 movff xC+0,opt_x_s1+0 ; xC= ppO2/mV as factor for sensor 1 | |
| 102 movff xC+1,opt_x_s1+1 | |
| 103 | 101 |
| 104 ; restore result | 102 ; restore result |
| 105 movff lo,xC+0 | 103 movff mpr+0,xC+0 |
| 106 movff hi,xC+1 | 104 movff mpr+1,xC+1 |
| 107 movff up,xC+2 | 105 movff mpr+2,xC+2 |
| 108 movff ex,xC+3 | 106 movff mpr+3,xC+3 |
| 109 | 107 |
| 110 ; compute factor for sensor 2 | 108 ; compute factor for sensor 2 |
| 111 movff o2_mv_sensor2+0,xB+0 | 109 MOVII sensor2_mv,xB |
| 112 movff o2_mv_sensor2+1,xB+1 | 110 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 113 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | 111 MOVII xC,opt_x_s2 ; xC = ppO2/mV as factor for sensor 2 |
| 114 movff xC+0,opt_x_s2+0 ; xC= ppO2/mV as factor for sensor 2 | |
| 115 movff xC+1,opt_x_s2+1 | |
| 116 | 112 |
| 117 ; restore result | 113 ; restore result |
| 118 movff lo,xC+0 | 114 movff mpr+0,xC+0 |
| 119 movff hi,xC+1 | 115 movff mpr+1,xC+1 |
| 120 movff up,xC+2 | 116 movff mpr+2,xC+2 |
| 121 movff ex,xC+3 | 117 movff mpr+3,xC+3 |
| 122 | 118 |
| 123 ; compute factor for sensor 3 | 119 ; compute factor for sensor 3 |
| 124 movff o2_mv_sensor3+0,xB+0 | 120 MOVII sensor3_mv,xB |
| 125 movff o2_mv_sensor3+1,xB+1 | 121 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 126 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | 122 MOVII xC,opt_x_s3 ; xC = ppO2/mV as factor for sensor 3 |
| 127 movff xC+0,opt_x_s3+0 ; xC= ppO2/mV as factor for sensor 3 | |
| 128 movff xC+1,opt_x_s3+1 | |
| 129 | 123 |
| 130 ; check sensor 1 for min/max mV | 124 ; check sensor 1 for min/max mV |
| 131 movff o2_mv_sensor1+0, sub_a+0 ; get mV from sensor 1 | 125 MOVII sensor1_mv,sub_a ; get mV from sensor 1 |
| 132 movff o2_mv_sensor1+1, sub_a+1 | |
| 133 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 | 126 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 |
| 134 TSTFSZ WREG ; sensor mV within thresholds? | 127 TSTFSZ WREG ; sensor mV within thresholds? |
| 135 bcf use_O2_sensor1 ; NO - clear usage flag | 128 bcf use_O2_sensor1 ; NO - clear usage flag |
| 136 | 129 |
| 137 ; check sensor 2 for min/max mV | 130 ; check sensor 2 for min/max mV |
| 138 movff o2_mv_sensor2+0, sub_a+0 ; get mV from sensor 2 | 131 MOVII sensor2_mv,sub_a ; get mV from sensor 2 |
| 139 movff o2_mv_sensor2+1, sub_a+1 | |
| 140 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 | 132 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 |
| 141 TSTFSZ WREG ; sensor mV within thresholds? | 133 TSTFSZ WREG ; sensor mV within thresholds? |
| 142 bcf use_O2_sensor2 ; NO - clear usage flag | 134 bcf use_O2_sensor2 ; NO - clear usage flag |
| 143 | 135 |
| 144 ; check sensor 3 for min/max mV | 136 ; check sensor 3 for min/max mV |
| 145 movff o2_mv_sensor3+0, sub_a+0 ; get mV from sensor 3 | 137 MOVII sensor3_mv,sub_a ; get mV from sensor 3 |
| 146 movff o2_mv_sensor3+1, sub_a+1 | |
| 147 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 | 138 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1 |
| 148 TSTFSZ WREG ; sensor mV within thresholds? | 139 TSTFSZ WREG ; sensor mV within thresholds? |
| 149 bcf use_O2_sensor3 ; NO - clear usage flag | 140 bcf use_O2_sensor3 ; NO - clear usage flag |
| 150 | 141 |
| 151 calibrate_mix2: | 142 calibrate_mix2: |
| 152 ; check for HUD | 143 ; check for HUD |
| 153 btfss hud_connection_ok ; HUD connection existing? | 144 btfss hud_connection_ok ; HUD connection existing? |
| 154 bra calibrate_mix3 ; NO - skip HUD part | 145 bra calibrate_mix3 ; NO - skip HUD part |
| 155 | 146 |
| 156 ; Copy disable flags from HUD digital input | 147 ; copy disable flags from HUD digital input |
| 157 btfss sensor1_active | 148 btfss sensor1_active |
| 158 bcf use_O2_sensor1 | 149 bcf use_O2_sensor1 |
| 159 btfss sensor2_active | 150 btfss sensor2_active |
| 160 bcf use_O2_sensor2 | 151 bcf use_O2_sensor2 |
| 161 btfss sensor3_active | 152 btfss sensor3_active |
| 168 btfss use_O2_sensor2 ; sensor 2 out of range? | 159 btfss use_O2_sensor2 ; sensor 2 out of range? |
| 169 bcf sensor2_calibrated_ok ; YES - disable this sensor | 160 bcf sensor2_calibrated_ok ; YES - disable this sensor |
| 170 btfss use_O2_sensor3 ; sensor 3 out of range? | 161 btfss use_O2_sensor3 ; sensor 3 out of range? |
| 171 bcf sensor3_calibrated_ok ; YES - disable this sensor | 162 bcf sensor3_calibrated_ok ; YES - disable this sensor |
| 172 | 163 |
| 173 ; When no sensor is found, enable all three to show error state and clear calibration factors | 164 ; when no sensor is found, enable all three to show error state and clear calibration factors |
| 174 btfsc use_O2_sensor1 | 165 btfsc use_O2_sensor1 |
| 175 return | 166 return |
| 176 btfsc use_O2_sensor2 | 167 btfsc use_O2_sensor2 |
| 177 return | 168 return |
| 178 btfsc use_O2_sensor3 | 169 btfsc use_O2_sensor3 |
| 179 return | 170 return |
| 180 ; Enable all sensors | 171 |
| 172 ; enable all sensors | |
| 181 bsf use_O2_sensor1 | 173 bsf use_O2_sensor1 |
| 182 bsf use_O2_sensor2 | 174 bsf use_O2_sensor2 |
| 183 bsf use_O2_sensor3 | 175 bsf use_O2_sensor3 |
| 184 ; Clear calibration factors | 176 ; clear calibration factors |
| 185 banksel opt_x_s1+0 | 177 banksel opt_x_s1 ; switch to bank options table |
| 186 clrf opt_x_s1+0 | 178 CLRI opt_x_s1 |
| 187 clrf opt_x_s1+1 | 179 CLRI opt_x_s2 |
| 188 clrf opt_x_s2+0 | 180 CLRI opt_x_s3 |
| 189 clrf opt_x_s2+1 | 181 banksel common ; back to bank common |
| 190 clrf opt_x_s3+0 | |
| 191 clrf opt_x_s3+1 | |
| 192 banksel common | |
| 193 return | 182 return |
| 194 | 183 |
| 195 calibrate_mix_helper: | 184 calibrate_mix_helper: |
| 196 movlw LOW min_mv ; load minimum threshold... | 185 MOVLI min_mv,sub_b ; load minimum threshold into sub_b |
| 197 movwf sub_b+0 ; ...into sub_b | |
| 198 movlw HIGH min_mv | |
| 199 movwf sub_b+1 | |
| 200 call sub16 ; sub_c = sub_a - sub_b | 186 call sub16 ; sub_c = sub_a - sub_b |
| 201 btfsc neg_flag ; sensor mV lower than minimum threshold? | 187 btfsc neg_flag ; sensor mV lower than minimum threshold? |
| 202 retlw .1 ; YES - return signaling threshold violation | 188 retlw .1 ; YES - return signaling threshold violation |
| 203 movlw LOW max_mv ; load maximum threshold... | 189 MOVLI max_mv,sub_b ; load maximum threshold into sub_b |
| 204 movwf sub_b+0 ; ...into sub_b | |
| 205 movlw HIGH max_mv | |
| 206 movwf sub_b+1 | |
| 207 call sub16 ; sub_c = sub_a - sub_b | 190 call sub16 ; sub_c = sub_a - sub_b |
| 208 btfss neg_flag ; sensor mV higher than maximum threshold? | 191 btfss neg_flag ; sensor mV higher than maximum threshold? |
| 209 retlw .1 ; YES - return signaling threshold violation | 192 retlw .1 ; YES - return signaling threshold violation |
| 210 retlw .0 ; NO - return signaling min/max ok | 193 retlw .0 ; NO - return signaling min/max ok |
| 211 | 194 |
| 212 | 195 |
| 213 global compute_mvolts_for_all_sensors | 196 global compute_mvolts_for_all_sensors |
| 214 compute_mvolts_for_all_sensors: ; compute mV or all sensors (S8 mode) | 197 compute_mvolts_for_all_sensors: ; compute mV or all sensors (S8 mode) |
| 215 ; compute AD results in 100µV steps (16bit/sensor) | 198 ; compute AD results in 100 µV steps (16 bit/sensor) |
| 216 ; 24bit AD result is in 244,1406541nV | 199 ; 24 bit AD result is in 244.1406541 nV |
| 217 ; Divide 24bit value through 409,5999512 -> 410 (0,01% error) | 200 ; divide 24 bit value by 409.5999512 -> 410 with only 0.01% error |
| 218 #DEFINE ad2mv_factor .410 | 201 #DEFINE ad2mv_factor .410 |
| 219 movlw LOW ad2mv_factor | 202 |
| 220 movwf xB+0 | 203 MOVLI ad2mv_factor,xB |
| 221 movlw HIGH ad2mv_factor | 204 |
| 222 movwf xB+1 | |
| 223 ; Sensor 1 | 205 ; Sensor 1 |
| 224 clrf xC+3 | 206 SMOVTT s8_rawdata_sensor1,xC ; ISR-safe copy of 3 bytes to xC |
| 225 movff s8_rawdata_sensor1+2,xC+2 | 207 clrf xC+3 ; clear MSB of xC |
| 226 movff s8_rawdata_sensor1+1,xC+1 | 208 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 227 movff s8_rawdata_sensor1+0,xC+0 | 209 MOVII xC,sensor1_mv ; in 100 µV steps |
| 228 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | 210 |
| 229 movff xC+1,o2_mv_sensor1+1 | |
| 230 movff xC+0,o2_mv_sensor1+0 ; in 100 uV steps | |
| 231 ; Sensor 2 | 211 ; Sensor 2 |
| 232 clrf xC+3 | 212 SMOVTT s8_rawdata_sensor2,xC ; ISR-safe copy of 3 bytes to xC |
| 233 movff s8_rawdata_sensor2+2,xC+2 | 213 clrf xC+3 ; clear MSB of xC |
| 234 movff s8_rawdata_sensor2+1,xC+1 | 214 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 235 movff s8_rawdata_sensor2+0,xC+0 | 215 MOVII xC,sensor2_mv ; in 100 µV steps |
| 236 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | 216 |
| 237 movff xC+1,o2_mv_sensor2+1 | |
| 238 movff xC+0,o2_mv_sensor2+0 ; in 100 uV steps | |
| 239 ; Sensor 3 | 217 ; Sensor 3 |
| 240 clrf xC+3 | 218 SMOVTT s8_rawdata_sensor3,xC ; ISR-safe copy of 3 bytes to xC |
| 241 movff s8_rawdata_sensor3+2,xC+2 | 219 clrf xC+3 ; clear MSB of xC |
| 242 movff s8_rawdata_sensor3+1,xC+1 | 220 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder |
| 243 movff s8_rawdata_sensor3+0,xC+0 | 221 MOVII xC,sensor3_mv ; in 100 µV steps |
| 244 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | 222 |
| 245 movff xC+1,o2_mv_sensor3+1 | |
| 246 movff xC+0,o2_mv_sensor3+0 ; in 100 uV steps | |
| 247 | |
| 248 bcf new_s8_data_available ; clear flag | |
| 249 return ; done | 223 return ; done |
| 250 | 224 |
| 225 | |
| 226 ENDIF ; _external_sensor | |
| 227 | |
| 228 ;============================================================================= | |
| 229 | |
| 251 END | 230 END |
