comparison src/calibrate.asm @ 582:b455b31ce022

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