Mercurial > public > hwos_code
comparison src/calibrate.asm @ 113:f3062a611eef
Merge
| author | heinrichsweikamp |
|---|---|
| date | Mon, 23 Jun 2014 16:14:33 +0200 |
| parents | |
| children | e3ac5b2021bc |
comparison
equal
deleted
inserted
replaced
| 112:a24581f0b372 | 113:f3062a611eef |
|---|---|
| 1 ;============================================================================= | |
| 2 ; | |
| 3 ; File calibration.asm | |
| 4 ; | |
| 5 ; o2 sensor calibration subroutines | |
| 6 ; | |
| 7 ; Copyright (c) 2014, Heinrichs Weikamp, all right reserved. | |
| 8 ;============================================================================= | |
| 9 | |
| 10 #include "ostc3.inc" | |
| 11 #include "shared_definitions.h" ; Mailbox between c and asm | |
| 12 #include "math.inc" | |
| 13 #include "adc_lightsensor.inc" | |
| 14 #include "eeprom_rs232.inc" | |
| 15 | |
| 16 calibrate CODE | |
| 17 | |
| 18 global calibrate_mix | |
| 19 calibrate_mix: | |
| 20 ; calibrate S8 HUD | |
| 21 btfss s8_digital ; S8 Digital? | |
| 22 bra calibrate_mix2 ; No | |
| 23 | |
| 24 clrf temp1 ; Chksum | |
| 25 movlw 0xAA ; Start Byte | |
| 26 addwf temp1,F | |
| 27 movff WREG,TXREG2 | |
| 28 call rs232_wait_tx2 | |
| 29 | |
| 30 movlw 0x31 ; Calibrate | |
| 31 addwf temp1,F | |
| 32 movff WREG,TXREG2 | |
| 33 call rs232_wait_tx2 | |
| 34 | |
| 35 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 | |
| 36 addwf temp1,F | |
| 37 movff WREG,TXREG2 | |
| 38 call rs232_wait_tx2 | |
| 39 | |
| 40 movff amb_pressure+0,WREG ; Ambient pressure | |
| 41 addwf temp1,F | |
| 42 movff WREG,TXREG2 | |
| 43 call rs232_wait_tx2 | |
| 44 movff amb_pressure+1,WREG | |
| 45 addwf temp1,F | |
| 46 movff WREG,TXREG2 | |
| 47 call rs232_wait_tx2 | |
| 48 | |
| 49 movff temp1,TXREG2 ; Chksum | |
| 50 call rs232_wait_tx2 | |
| 51 | |
| 52 calibrate_mix2: | |
| 53 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 | |
| 54 mullw .100 | |
| 55 movff PRODL,xA+0 | |
| 56 movff PRODH,xA+1 | |
| 57 ; (%O2*100)*[ambient,mbar]/100 -> xC | |
| 58 movff amb_pressure+0,xB+0 | |
| 59 movff amb_pressure+1,xB+1 | |
| 60 call mult16x16 ;xA*xB=xC | |
| 61 movlw LOW .100 | |
| 62 movwf xB+0 | |
| 63 movlw HIGH .100 | |
| 64 movwf xB+1 | |
| 65 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 66 movff o2_mv_sensor1+0,xB+0 | |
| 67 movff o2_mv_sensor1+1,xB+1 | |
| 68 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 69 ; xC= ppO2/mV | |
| 70 movff xC+0,opt_x_s1+0 | |
| 71 movff xC+1,opt_x_s1+1 ; Factor for Sensor1 | |
| 72 | |
| 73 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 | |
| 74 mullw .100 | |
| 75 movff PRODL,xA+0 | |
| 76 movff PRODH,xA+1 | |
| 77 ; (%O2*100)*[ambient,mbar]/100 -> xC | |
| 78 movff amb_pressure+0,xB+0 | |
| 79 movff amb_pressure+1,xB+1 | |
| 80 call mult16x16 ;xA*xB=xC | |
| 81 movlw LOW .100 | |
| 82 movwf xB+0 | |
| 83 movlw HIGH .100 | |
| 84 movwf xB+1 | |
| 85 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 86 movff o2_mv_sensor2+0,xB+0 | |
| 87 movff o2_mv_sensor2+1,xB+1 | |
| 88 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 89 ; xC= ppO2/mV | |
| 90 movff xC+0,opt_x_s2+0 | |
| 91 movff xC+1,opt_x_s2+1 ; Factor for Sensor2 | |
| 92 | |
| 93 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2 | |
| 94 mullw .100 | |
| 95 movff PRODL,xA+0 | |
| 96 movff PRODH,xA+1 | |
| 97 ; (%O2*100)*[ambient,mbar]/100 -> xC | |
| 98 movff amb_pressure+0,xB+0 | |
| 99 movff amb_pressure+1,xB+1 | |
| 100 call mult16x16 ;xA*xB=xC | |
| 101 movlw LOW .100 | |
| 102 movwf xB+0 | |
| 103 movlw HIGH .100 | |
| 104 movwf xB+1 | |
| 105 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 106 movff o2_mv_sensor3+0,xB+0 | |
| 107 movff o2_mv_sensor3+1,xB+1 | |
| 108 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 109 ; xC= ppO2/mV | |
| 110 movff xC+0,opt_x_s3+0 | |
| 111 movff xC+1,opt_x_s3+1 ; Factor for Sensor3 | |
| 112 | |
| 113 ; Result is in 100µV | |
| 114 movff o2_mv_sensor1+0, sub_a+0 | |
| 115 movff o2_mv_sensor1+1, sub_a+1 | |
| 116 movlw LOW min_mv | |
| 117 movwf sub_b+0 | |
| 118 movlw HIGH min_mv | |
| 119 movwf sub_b+1 | |
| 120 call sub16 ; sub_c = sub_a - sub_b | |
| 121 bsf sensor1_active ; Sensor active! | |
| 122 btfsc neg_flag | |
| 123 bcf sensor1_active | |
| 124 | |
| 125 ; Result is in 100µV | |
| 126 movff o2_mv_sensor2+0, sub_a+0 | |
| 127 movff o2_mv_sensor2+1, sub_a+1 | |
| 128 movlw LOW min_mv | |
| 129 movwf sub_b+0 | |
| 130 movlw HIGH min_mv | |
| 131 movwf sub_b+1 | |
| 132 call sub16 ; sub_c = sub_a - sub_b | |
| 133 bsf sensor2_active ; Sensor active! | |
| 134 btfsc neg_flag | |
| 135 bcf sensor2_active | |
| 136 | |
| 137 ; Result is in 100µV | |
| 138 movff o2_mv_sensor3+0, sub_a+0 | |
| 139 movff o2_mv_sensor3+1, sub_a+1 | |
| 140 movlw LOW min_mv | |
| 141 movwf sub_b+0 | |
| 142 movlw HIGH min_mv | |
| 143 movwf sub_b+1 | |
| 144 call sub16 ; sub_c = sub_a - sub_b | |
| 145 bsf sensor3_active ; Sensor active! | |
| 146 btfsc neg_flag | |
| 147 bcf sensor3_active | |
| 148 | |
| 149 ; When no sensor is found, enable all three to show error state | |
| 150 btfsc sensor1_active | |
| 151 return | |
| 152 btfsc sensor2_active | |
| 153 return | |
| 154 btfsc sensor3_active | |
| 155 return | |
| 156 bsf sensor1_active | |
| 157 bsf sensor2_active | |
| 158 bsf sensor3_active | |
| 159 ; Clear factors | |
| 160 banksel opt_x_s1+0 | |
| 161 clrf opt_x_s1+0 | |
| 162 clrf opt_x_s1+1 | |
| 163 clrf opt_x_s2+0 | |
| 164 clrf opt_x_s2+1 | |
| 165 clrf opt_x_s3+0 | |
| 166 clrf opt_x_s3+1 | |
| 167 banksel common | |
| 168 return | |
| 169 | |
| 170 compute_ppo2_analog: | |
| 171 call get_analog_inputs | |
| 172 bra compute_ppo2_common | |
| 173 | |
| 174 global compute_ppo2 ; compute mv_sensorX and ppo2_sensorX arrays | |
| 175 compute_ppo2: | |
| 176 btfss c3_hardware ; C3 hardware? | |
| 177 return ; No | |
| 178 | |
| 179 btfss s8_digital ; =1: Digital I/O | |
| 180 bra compute_ppo2_analog ; use analog | |
| 181 | |
| 182 ; use digital | |
| 183 btfss new_s8_data_available ; =1: New data frame recieved | |
| 184 return | |
| 185 call compute_mvolts_for_all_sensors | |
| 186 | |
| 187 compute_ppo2_common: | |
| 188 ; o2_mv_sensor1:2 * opt_x_s1:2 = o2_ppo2_sensor1/10000 | |
| 189 movff o2_mv_sensor1+0,xA+0 | |
| 190 movff o2_mv_sensor1+1,xA+1 | |
| 191 movff opt_x_s1+0,xB+0 | |
| 192 movff opt_x_s1+1,xB+1 | |
| 193 call mult16x16 ;xA:2*xB:2=xC:4 | |
| 194 movlw LOW .1000 | |
| 195 movwf xB+0 | |
| 196 movlw HIGH .1000 | |
| 197 movwf xB+1 | |
| 198 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 199 movlw d'1' | |
| 200 addwf xC+0,F | |
| 201 movlw d'0' | |
| 202 addwfc xC+1,F | |
| 203 movff xC+0,o2_ppo2_sensor1+0 | |
| 204 movff xC+1,o2_ppo2_sensor1+1 ; result in 0.01bar | |
| 205 ; Set to zero if sensor is not active! | |
| 206 btfss sensor1_active | |
| 207 clrf o2_ppo2_sensor1+0 | |
| 208 btfss sensor1_active | |
| 209 clrf o2_ppo2_sensor1+1 | |
| 210 | |
| 211 ; o2_mv_sensor2:2 * opt_x_s1:2 = o2_ppo2_sensor2/10000 | |
| 212 movff o2_mv_sensor2+0,xA+0 | |
| 213 movff o2_mv_sensor2+1,xA+1 | |
| 214 movff opt_x_s2+0,xB+0 | |
| 215 movff opt_x_s2+1,xB+1 | |
| 216 call mult16x16 ;xA:2*xB:2=xC:4 | |
| 217 movlw LOW .1000 | |
| 218 movwf xB+0 | |
| 219 movlw HIGH .1000 | |
| 220 movwf xB+1 | |
| 221 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 222 movlw d'1' | |
| 223 addwf xC+0,F | |
| 224 movlw d'0' | |
| 225 addwfc xC+1,F | |
| 226 movff xC+0,o2_ppo2_sensor2+0 | |
| 227 movff xC+1,o2_ppo2_sensor2+1 ; result in 0.01bar | |
| 228 ; Set to zero if sensor is not active! | |
| 229 btfss sensor2_active | |
| 230 clrf o2_ppo2_sensor2+0 | |
| 231 btfss sensor2_active | |
| 232 clrf o2_ppo2_sensor2+1 | |
| 233 | |
| 234 ; o2_mv_sensor3:2 * opt_x_s1:2 = o2_ppo2_sensor3/10000 | |
| 235 movff o2_mv_sensor3+0,xA+0 | |
| 236 movff o2_mv_sensor3+1,xA+1 | |
| 237 movff opt_x_s3+0,xB+0 | |
| 238 movff opt_x_s3+1,xB+1 | |
| 239 call mult16x16 ;xA:2*xB:2=xC:4 | |
| 240 movlw LOW .1000 | |
| 241 movwf xB+0 | |
| 242 movlw HIGH .1000 | |
| 243 movwf xB+1 | |
| 244 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 245 movlw d'1' | |
| 246 addwf xC+0,F | |
| 247 movlw d'0' | |
| 248 addwfc xC+1,F | |
| 249 movff xC+0,o2_ppo2_sensor3+0 | |
| 250 movff xC+1,o2_ppo2_sensor3+1 ; result in 0.01bar | |
| 251 ; Set to zero if sensor is not active! | |
| 252 btfss sensor3_active | |
| 253 clrf o2_ppo2_sensor3+0 | |
| 254 btfss sensor3_active | |
| 255 clrf o2_ppo2_sensor3+1 | |
| 256 | |
| 257 return ; Done. | |
| 258 | |
| 259 | |
| 260 compute_mvolts_for_all_sensors: ; Compute mV or all sensors (S8 Mode) | |
| 261 ; compute AD results in 100µV steps (16bit/sensor) | |
| 262 ; 24bit AD result is in 244,1406541nV | |
| 263 ; Devide 24bit value through 409,5999512 -> 410 (0,01% error) | |
| 264 #DEFINE ad2mv_factor .410 | |
| 265 ; Sensor 1 | |
| 266 clrf xC+3 | |
| 267 movff ir_buffer+.6,xC+2 | |
| 268 movff ir_buffer+.5,xC+1 | |
| 269 movff ir_buffer+.4,xC+0 | |
| 270 movlw LOW ad2mv_factor | |
| 271 movwf xB+0 | |
| 272 movlw HIGH ad2mv_factor | |
| 273 movwf xB+1 | |
| 274 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 275 movff xC+1,o2_mv_sensor1+1 | |
| 276 movff xC+0,o2_mv_sensor1+0 ; in 100uV steps | |
| 277 ; Sensor 2 | |
| 278 clrf xC+3 | |
| 279 movff ir_buffer+.9,xC+2 | |
| 280 movff ir_buffer+.8,xC+1 | |
| 281 movff ir_buffer+.7,xC+0 | |
| 282 movlw LOW ad2mv_factor | |
| 283 movwf xB+0 | |
| 284 movlw HIGH ad2mv_factor | |
| 285 movwf xB+1 | |
| 286 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 287 movff xC+1,o2_mv_sensor2+1 | |
| 288 movff xC+0,o2_mv_sensor2+0 ; in 100uV steps | |
| 289 ; Sensor 3 | |
| 290 clrf xC+3 | |
| 291 movff ir_buffer+.12,xC+2 | |
| 292 movff ir_buffer+.11,xC+1 | |
| 293 movff ir_buffer+.10,xC+0 | |
| 294 movlw LOW ad2mv_factor | |
| 295 movwf xB+0 | |
| 296 movlw HIGH ad2mv_factor | |
| 297 movwf xB+1 | |
| 298 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder | |
| 299 movff xC+1,o2_mv_sensor3+1 | |
| 300 movff xC+0,o2_mv_sensor3+0 ; in 100uV steps | |
| 301 | |
| 302 bcf new_s8_data_available ; Clear flag | |
| 303 return ; Done. | |
| 304 | |
| 305 | |
| 306 | |
| 307 END |
