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 |