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 |