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