comparison 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
comparison
equal deleted inserted replaced
603:00b24fb4324d 604:ca4556fb60b9
1 ;============================================================================= 1 ;=============================================================================
2 ; 2 ;
3 ; File calibration.asm REFACTORED VERSION V2.98 3 ; File calibration.asm REFACTORED VERSION V2.98b
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 ;=============================================================================
9 9
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"
15 16
16 17
17 calibrate CODE 18 calibrate CODE
18 19
19 global check_sensors ; Check O2 sensor thresholds for fallback and voting logic 20
20 check_sensors: 21 global transmit_setpoint ; transmit current setpoint from WREG (in cbar) to external electronics
21 ; Check min_mv 22 transmit_setpoint:
22 movff o2_mv_sensor1+0, sub_a+0 23 return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!!
24 btfss s8_digital ; S8 Digital connection existing?
25 return ; NO - ignore
26 ; YES - transmit setpoint from WREG
27 clrf lo ; initialize checksum
28 movwf hi ; store setpoint
29 movlw 0xAA ; start byte
30 rcall tx_to_HUD ; transmit to HUD
31 movlw 0x60 ; command new SP
32 rcall tx_to_HUD ; transmit to HUD
33 movff hi,WREG ; SP in cbar
34 rcall tx_to_HUD ; transmit to HUD
35 movff lo,WREG ; checksum
36 rcall tx_to_HUD_cs ; transmit checksum
37 return
38
39 tx_to_HUD: ; entry point to transmit a byte to the HUD
40 addwf lo,F ; add byte to checksum
41 tx_to_HUD_cs: ; entry point to transmit the checksum
42 movff WREG,TXREG2 ; transmit byte
43 call rs232_wait_tx2 ; wait for UART
44 return
45
46
47 global calibrate_mix
48 calibrate_mix:
49 ; set usage and calibration flags as per default
50 bsf use_O2_sensor1
51 bsf use_O2_sensor2
52 bsf use_O2_sensor3
53 bsf sensor1_calibrated_ok
54 bsf sensor2_calibrated_ok
55 bsf sensor3_calibrated_ok
56
57 ; check for HUD
58 btfss s8_digital ; S8 Digital connection existing?
59 bra calibrate_mix1 ; NO - skip HUD part
60
61 ; calibrate any S8-connected HUD
62 clrf lo ; initialize checksum
63 movlw 0xAA ; start byte
64 rcall tx_to_HUD ; transmit to HUD
65 movlw 0x31 ; calibration command
66 rcall tx_to_HUD ; transmit to HUD
67 movff opt_calibration_O2_ratio,WREG ; calibration gas %O2
68 rcall tx_to_HUD ; transmit to HUD
69 movff amb_pressure+0,WREG ; ambient pressure low byte
70 rcall tx_to_HUD ; transmit to HUD
71 movff amb_pressure+1,WREG ; ambient pressure high byte
72 rcall tx_to_HUD ; transmit to HUD
73 movff lo,WREG ; checksum
74 rcall tx_to_HUD_cs ; transmit to HUD
75 ; bra calibrate_mix2
76
77 ; calibrate internal sensors
78 calibrate_mix1: ; compute %O2 * 100 * ambient_pressure[mbar] / 100
79 movff opt_calibration_O2_ratio,WREG
80 mullw .100
81 movff PRODL,xA+0
82 movff PRODH,xA+1
83 SAFE_2BYTE_COPY amb_pressure,xB
84 call mult16x16 ; xA*xB=xC
85 movlw LOW .100
86 movwf xB+0
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
91 ; keep a copy of the result
92 movff xC+0,lo
93 movff xC+1,hi
94 movff xC+2,up
95 movff xC+3,ex
96
97 ; compute factor for sensor 1
98 movff o2_mv_sensor1+0,xB+0
99 movff o2_mv_sensor1+1,xB+1
100 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
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
104 ; restore result
105 movff lo,xC+0
106 movff hi,xC+1
107 movff up,xC+2
108 movff ex,xC+3
109
110 ; compute factor for sensor 2
111 movff o2_mv_sensor2+0,xB+0
112 movff o2_mv_sensor2+1,xB+1
113 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
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
117 ; restore result
118 movff lo,xC+0
119 movff hi,xC+1
120 movff up,xC+2
121 movff ex,xC+3
122
123 ; compute factor for sensor 3
124 movff o2_mv_sensor3+0,xB+0
125 movff o2_mv_sensor3+1,xB+1
126 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
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
130 ; check sensor 1 for min/max mV
131 movff o2_mv_sensor1+0, sub_a+0 ; get mV from sensor 1
23 movff o2_mv_sensor1+1, sub_a+1 132 movff o2_mv_sensor1+1, sub_a+1
24 movlw LOW min_mv 133 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1
25 movwf sub_b+0 134 TSTFSZ WREG ; sensor mV within thresholds?
26 movlw HIGH min_mv 135 bcf use_O2_sensor1 ; NO - clear usage flag
27 movwf sub_b+1 136
28 call sub16 ; sub_c = sub_a - sub_b 137 ; check sensor 2 for min/max mV
29 bsf use_O2_sensor1 ;=1: Use this sensor for deco 138 movff o2_mv_sensor2+0, sub_a+0 ; get mV from sensor 2
30 btfsc neg_flag
31 bcf use_O2_sensor1 ;=1: Use this sensor for deco
32
33 movff o2_mv_sensor2+0, sub_a+0
34 movff o2_mv_sensor2+1, sub_a+1 139 movff o2_mv_sensor2+1, sub_a+1
35 movlw LOW min_mv 140 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1
36 movwf sub_b+0 141 TSTFSZ WREG ; sensor mV within thresholds?
37 movlw HIGH min_mv 142 bcf use_O2_sensor2 ; NO - clear usage flag
38 movwf sub_b+1 143
39 call sub16 ; sub_c = sub_a - sub_b 144 ; check sensor 3 for min/max mV
40 bsf use_O2_sensor2 ;=1: Use this sensor for deco 145 movff o2_mv_sensor3+0, sub_a+0 ; get mV from sensor 3
41 btfsc neg_flag
42 bcf use_O2_sensor2 ;=1: Use this sensor for deco
43
44 movff o2_mv_sensor3+0, sub_a+0
45 movff o2_mv_sensor3+1, sub_a+1 146 movff o2_mv_sensor3+1, sub_a+1
46 movlw LOW min_mv 147 rcall calibrate_mix_helper ; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1
47 movwf sub_b+0 148 TSTFSZ WREG ; sensor mV within thresholds?
48 movlw HIGH min_mv 149 bcf use_O2_sensor3 ; NO - clear usage flag
49 movwf sub_b+1 150
50 call sub16 ; sub_c = sub_a - sub_b 151 calibrate_mix2:
51 bsf use_O2_sensor3 ;=1: Use this sensor for deco 152 ; check for HUD
52 btfsc neg_flag 153 btfss hud_connection_ok ; HUD connection existing?
53 bcf use_O2_sensor3 ;=1: Use this sensor for deco 154 bra calibrate_mix3 ; NO - skip HUD part
54 155
55 ; Check max_mv 156 ; Copy disable flags from HUD digital input
56 movff o2_mv_sensor1+0, sub_a+0
57 movff o2_mv_sensor1+1, sub_a+1
58 movlw LOW max_mv
59 movwf sub_b+0
60 movlw HIGH max_mv
61 movwf sub_b+1
62 call sub16 ; sub_c = sub_a - sub_b
63 btfss neg_flag
64 bcf use_O2_sensor1 ;=1: Use this sensor for deco
65
66 movff o2_mv_sensor2+0, sub_a+0
67 movff o2_mv_sensor2+1, sub_a+1
68 movlw LOW max_mv
69 movwf sub_b+0
70 movlw HIGH max_mv
71 movwf sub_b+1
72 call sub16 ; sub_c = sub_a - sub_b
73 btfss neg_flag
74 bcf use_O2_sensor2 ;=1: Use this sensor for deco
75
76 movff o2_mv_sensor3+0, sub_a+0
77 movff o2_mv_sensor3+1, sub_a+1
78 movlw LOW max_mv
79 movwf sub_b+0
80 movlw HIGH max_mv
81 movwf sub_b+1
82 call sub16 ; sub_c = sub_a - sub_b
83 btfss neg_flag
84 bcf use_O2_sensor3 ;=1: Use this sensor for deco
85
86 btfss hud_connection_ok ;=1: HUD connection ok
87 bra check_sensor2 ; No HUD/Digital data
88
89 ; Copy disable flags from digital input
90 btfss sensor1_active 157 btfss sensor1_active
91 bcf use_O2_sensor1 158 bcf use_O2_sensor1
92 btfss sensor2_active 159 btfss sensor2_active
93 bcf use_O2_sensor2 160 bcf use_O2_sensor2
94 btfss sensor3_active 161 btfss sensor3_active
95 bcf use_O2_sensor3 162 bcf use_O2_sensor3
96 return 163
97 164 calibrate_mix3:
98 check_sensor2: 165 ; clear calibration flags if sensors are not found to be ok
99 ; Copy disable flags from internal calibration routine 166 btfss use_O2_sensor1 ; sensor 1 out of range?
100 btfss sensor1_calibrated_ok 167 bcf sensor1_calibrated_ok ; YES - disable this sensor
101 bcf use_O2_sensor1 168 btfss use_O2_sensor2 ; sensor 2 out of range?
102 btfss sensor2_calibrated_ok 169 bcf sensor2_calibrated_ok ; YES - disable this sensor
103 bcf use_O2_sensor2 170 btfss use_O2_sensor3 ; sensor 3 out of range?
104 btfss sensor3_calibrated_ok 171 bcf sensor3_calibrated_ok ; YES - disable this sensor
105 bcf use_O2_sensor3 172
106 return 173 ; When no sensor is found, enable all three to show error state and clear calibration factors
107
108
109 global calibrate_mix
110 calibrate_mix:
111 ; calibrate S8 HUD
112 btfss s8_digital ; S8 Digital?
113 bra calibrate_mix2 ; No
114
115 ; Yes, calibrate any S8-connected HUD
116 clrf lo ; Checksum
117 movlw 0xAA ; Start Byte
118 addwf lo,F
119 movff WREG,TXREG2
120 call rs232_wait_tx2
121
122 movlw 0x31 ; Calibrate
123 addwf lo,F
124 movff WREG,TXREG2
125 call rs232_wait_tx2
126
127 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2
128 addwf lo,F
129 movff WREG,TXREG2
130 call rs232_wait_tx2
131
132 movff amb_pressure+0,WREG ; Ambient pressure
133 addwf lo,F
134 movff WREG,TXREG2
135 call rs232_wait_tx2
136 movff amb_pressure+1,WREG
137 addwf lo,F
138 movff WREG,TXREG2
139 call rs232_wait_tx2
140
141 movff lo,TXREG2 ; Checksum
142 call rs232_wait_tx2
143
144 calibrate_mix2:
145 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2
146 mullw .100
147 movff PRODL,xA+0
148 movff PRODH,xA+1
149 ; (%O2*100)*[ambient,mbar]/100 -> xC
150 movff amb_pressure+0,xB+0
151 movff amb_pressure+1,xB+1
152 rcall calibrate_mix2_helper
153 movff o2_mv_sensor1+0,xB+0
154 movff o2_mv_sensor1+1,xB+1
155 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
156 ; xC= ppO2/mV
157 movff xC+0,opt_x_s1+0
158 movff xC+1,opt_x_s1+1 ; Factor for Sensor1
159
160 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2
161 mullw .100
162 movff PRODL,xA+0
163 movff PRODH,xA+1
164 ; (%O2*100)*[ambient,mbar]/100 -> xC
165 movff amb_pressure+0,xB+0
166 movff amb_pressure+1,xB+1
167 rcall calibrate_mix2_helper
168 movff o2_mv_sensor2+0,xB+0
169 movff o2_mv_sensor2+1,xB+1
170 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
171 ; xC= ppO2/mV
172 movff xC+0,opt_x_s2+0
173 movff xC+1,opt_x_s2+1 ; Factor for Sensor2
174
175 movff opt_calibration_O2_ratio,WREG ; Calibration gas %O2
176 mullw .100
177 movff PRODL,xA+0
178 movff PRODH,xA+1
179 ; (%O2*100)*[ambient,mbar]/100 -> xC
180 movff amb_pressure+0,xB+0
181 movff amb_pressure+1,xB+1
182 rcall calibrate_mix2_helper
183 movff o2_mv_sensor3+0,xB+0
184 movff o2_mv_sensor3+1,xB+1
185 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
186 ; xC= ppO2/mV
187 movff xC+0,opt_x_s3+0
188 movff xC+1,opt_x_s3+1 ; Factor for Sensor3
189
190 bsf sensor1_calibrated_ok
191 bsf sensor2_calibrated_ok
192 bsf sensor3_calibrated_ok ; Set flags prior check
193
194 rcall check_sensors ; Check O2 sensor thresholds min_mv and max_mv and set use_02_sensorX flags
195 ; initialize internal calibration flags
196 btfss use_O2_sensor1 ; Sensor out of range?
197 bcf sensor1_calibrated_ok ; Yes, disable this sensor
198 btfss use_O2_sensor2 ; Sensor out of range?
199 bcf sensor2_calibrated_ok ; Yes, disable this sensor
200 btfss use_O2_sensor3 ; Sensor out of range?
201 bcf sensor3_calibrated_ok ; Yes, disable this sensor
202
203 ; When no sensor is found, enable all three to show error state
204 btfsc use_O2_sensor1 174 btfsc use_O2_sensor1
205 return 175 return
206 btfsc use_O2_sensor2 176 btfsc use_O2_sensor2
207 return 177 return
208 btfsc use_O2_sensor3 178 btfsc use_O2_sensor3
209 return 179 return
180 ; Enable all sensors
210 bsf use_O2_sensor1 181 bsf use_O2_sensor1
211 bsf use_O2_sensor2 182 bsf use_O2_sensor2
212 bsf use_O2_sensor3 183 bsf use_O2_sensor3
213 ; Clear factors 184 ; Clear calibration factors
214 banksel opt_x_s1+0 185 banksel opt_x_s1+0
215 clrf opt_x_s1+0 186 clrf opt_x_s1+0
216 clrf opt_x_s1+1 187 clrf opt_x_s1+1
217 clrf opt_x_s2+0 188 clrf opt_x_s2+0
218 clrf opt_x_s2+1 189 clrf opt_x_s2+1
219 clrf opt_x_s3+0 190 clrf opt_x_s3+0
220 clrf opt_x_s3+1 191 clrf opt_x_s3+1
221 banksel common 192 banksel common
222 return 193 return
223 194
224 195 calibrate_mix_helper:
225 calibrate_mix2_helper: 196 movlw LOW min_mv ; load minimum threshold...
226 call mult16x16 ; xA*xB=xC 197 movwf sub_b+0 ; ...into sub_b
227 movlw LOW .100 198 movlw HIGH min_mv
228 movwf xB+0 199 movwf sub_b+1
229 movlw HIGH .100 200 call sub16 ; sub_c = sub_a - sub_b
230 movwf xB+1 201 btfsc neg_flag ; sensor mV lower than minimum threshold?
231 goto div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder (And return) 202 retlw .1 ; YES - return signaling threshold violation
203 movlw LOW max_mv ; load maximum threshold...
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
208 btfss neg_flag ; sensor mV higher than maximum threshold?
209 retlw .1 ; YES - return signaling threshold violation
210 retlw .0 ; NO - return signaling min/max ok
232 211
233 212
234 global compute_mvolts_for_all_sensors 213 global compute_mvolts_for_all_sensors
235 compute_mvolts_for_all_sensors: ; Compute mV or all sensors (S8 Mode) 214 compute_mvolts_for_all_sensors: ; compute mV or all sensors (S8 mode)
236 ; compute AD results in 100µV steps (16bit/sensor) 215 ; compute AD results in 100µV steps (16bit/sensor)
237 ; 24bit AD result is in 244,1406541nV 216 ; 24bit AD result is in 244,1406541nV
238 ; Divide 24bit value through 409,5999512 -> 410 (0,01% error) 217 ; Divide 24bit value through 409,5999512 -> 410 (0,01% error)
239 #DEFINE ad2mv_factor .410 218 #DEFINE ad2mv_factor .410
219 movlw LOW ad2mv_factor
220 movwf xB+0
221 movlw HIGH ad2mv_factor
222 movwf xB+1
240 ; Sensor 1 223 ; Sensor 1
241 clrf xC+3 224 clrf xC+3
242 movff s8_rawdata_sensor1+2,xC+2 225 movff s8_rawdata_sensor1+2,xC+2
243 movff s8_rawdata_sensor1+1,xC+1 226 movff s8_rawdata_sensor1+1,xC+1
244 movff s8_rawdata_sensor1+0,xC+0 227 movff s8_rawdata_sensor1+0,xC+0
245 movlw LOW ad2mv_factor
246 movwf xB+0
247 movlw HIGH ad2mv_factor
248 movwf xB+1
249 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder 228 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
250 movff xC+1,o2_mv_sensor1+1 229 movff xC+1,o2_mv_sensor1+1
251 movff xC+0,o2_mv_sensor1+0 ; in 100uV steps 230 movff xC+0,o2_mv_sensor1+0 ; in 100 uV steps
252 ; Sensor 2 231 ; Sensor 2
253 clrf xC+3 232 clrf xC+3
254 movff s8_rawdata_sensor2+2,xC+2 233 movff s8_rawdata_sensor2+2,xC+2
255 movff s8_rawdata_sensor2+1,xC+1 234 movff s8_rawdata_sensor2+1,xC+1
256 movff s8_rawdata_sensor2+0,xC+0 235 movff s8_rawdata_sensor2+0,xC+0
257 movlw LOW ad2mv_factor
258 movwf xB+0
259 movlw HIGH ad2mv_factor
260 movwf xB+1
261 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder 236 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
262 movff xC+1,o2_mv_sensor2+1 237 movff xC+1,o2_mv_sensor2+1
263 movff xC+0,o2_mv_sensor2+0 ; in 100uV steps 238 movff xC+0,o2_mv_sensor2+0 ; in 100 uV steps
264 ; Sensor 3 239 ; Sensor 3
265 clrf xC+3 240 clrf xC+3
266 movff s8_rawdata_sensor3+2,xC+2 241 movff s8_rawdata_sensor3+2,xC+2
267 movff s8_rawdata_sensor3+1,xC+1 242 movff s8_rawdata_sensor3+1,xC+1
268 movff s8_rawdata_sensor3+0,xC+0 243 movff s8_rawdata_sensor3+0,xC+0
269 movlw LOW ad2mv_factor
270 movwf xB+0
271 movlw HIGH ad2mv_factor
272 movwf xB+1
273 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder 244 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
274 movff xC+1,o2_mv_sensor3+1 245 movff xC+1,o2_mv_sensor3+1
275 movff xC+0,o2_mv_sensor3+0 ; in 100uV steps 246 movff xC+0,o2_mv_sensor3+0 ; in 100 uV steps
276 247
277 bcf new_s8_data_available ; Clear flag 248 bcf new_s8_data_available ; clear flag
278 return ; Done. 249 return ; done
279
280
281 global transmit_setpoint ; Transmit current setpoint from WREG (in cbar) to external electronics
282 transmit_setpoint:
283 return ; !!!! FUNCTION IS CURRENTLY DISABLED !!!!
284 btfss s8_digital ; S8 Digital?
285 return ; No, ignore
286
287 ; Yes, transmit setpoint from WREG
288 movwf hi ; Store setpoint
289 clrf lo ; Checksum
290 movlw 0xAA ; Start Byte
291 addwf lo,F
292 movff WREG,TXREG2
293 call rs232_wait_tx2
294
295 movlw 0x60 ; New SP
296 addwf lo,F
297 movff WREG,TXREG2
298 call rs232_wait_tx2
299
300 movff hi,WREG ; SP in cbar
301 addwf lo,F
302 movff WREG,TXREG2
303 call rs232_wait_tx2
304
305 movff lo,TXREG2 ; Checksum
306 call rs232_wait_tx2
307 return
308
309 250
310 END 251 END