comparison src/adc_lightsensor.asm @ 623:c40025d8e750

3.03 beta released
author heinrichsweikamp
date Mon, 03 Jun 2019 14:01:48 +0200
parents b87f23fae743
children cd58f7fc86db
comparison
equal deleted inserted replaced
622:02d1386429a6 623:c40025d8e750
1 ;============================================================================= 1 ;=============================================================================
2 ; 2 ;
3 ; File adc.asm V2.99e 3 ; File adc_lightsensor.asm combined next generation V3.03.2
4 ; 4 ;
5 ; 5 ;
6 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. 6 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
7 ;============================================================================= 7 ;=============================================================================
8 ; HISTORY 8 ; HISTORY
12 #include "math.inc" 12 #include "math.inc"
13 #include "wait.inc" 13 #include "wait.inc"
14 #include "eeprom_rs232.inc" 14 #include "eeprom_rs232.inc"
15 #include "i2c.inc" 15 #include "i2c.inc"
16 16
17 extern reset_battery_internal_only 17
18 18 adc_light CODE
19 adc_light CODE
20 19
21 ;============================================================================= 20 ;=============================================================================
22 21
23 wait_adc: 22 wait_adc: ; bank-safe
24 movwf ADCON0 23 movwf ADCON0
25 nop
26 nop
27 nop 24 nop
28 bsf ADCON0,1 ; start ADC 25 bsf ADCON0,1 ; start ADC
29 wait_adc2: 26 wait_adc2:
30 btfsc ADCON0,1 ; wait... 27 btfsc ADCON0,1 ; wait...
31 bra wait_adc2 28 bra wait_adc2
32 return 29 return
33 30
34 global get_battery_voltage 31 global get_battery_voltage
35 get_battery_voltage: ; starts ADC and waits until finished 32 get_battery_voltage: ; start ADC and wait until finished
36 btfss battery_gauge_available 33 btfss battery_gauge_available ; battery gauge IC available?
37 bra get_battery_voltage1 ; normal ostc3 hardware 34 bra get_battery_voltage_2 ; NO - OSTC hardware without gauge IC
38 35 call lt2942_get_accumulated_charge ; YES - read coulomb counter
39 call lt2942_get_accumulated_charge 36 call lt2942_get_voltage ; - read battery voltage
40 call lt2942_get_voltage 37 call lt2942_get_temperature ; - read battery temperature
41 call lt2942_get_temperature 38 tstfsz batt_voltage+1 ; - read voltage < 256 mV ?
42 39 bra get_battery_voltage_1 ; NO - proceed
43 tstfsz batt_voltage+1 ; < 256 mV ? 40 call lt2942_get_accumulated_charge ; YES - re-read coulomb counter
44 bra get_battery_voltage_noretry ; NO 41 call lt2942_get_voltage ; - re-read battery voltage
45 42 call lt2942_get_temperature ; - re-read battery temperature
46 ; Retry 43 ;bra get_battery_voltage_1 ; - proceed
47 call lt2942_get_accumulated_charge 44
48 call lt2942_get_voltage 45 get_battery_voltage_1:
49 call lt2942_get_temperature 46 btfsc divemode ; in dive mode?
50 47 return ; YES - done
51 get_battery_voltage_noretry: 48
52 btfsc divemode 49 bcf cv_active ; clear CV charing status by default
53 return ; not in divemode 50 bcf cc_active ; clear CC charing status ny default
54 51 bcf LEDr ; switch off red LED
55 bcf cv_active 52 bcf TRISJ,2 ; activate Chrg-Out output
56 bcf cc_active 53 bsf CHRG_OUT ; start charger
57 bcf LEDr 54 btfss CHRG_IN ; charging?
58 bcf TRISJ,2 ; Chrg-Out output 55 bra charge_cc_active ; YES - charging in CC mode
59 bsf CHRG_OUT 56 bcf CHRG_OUT ; NO - stop charger
60 57 bsf TRISJ,2 ; - set Chrg-Out output to high impedance
61 btfss CHRG_IN 58 WAITMS d'1' ; - wait 1 ms
62 bra charge_cc_active 59 btfsc CHRG_IN ; - still charging?
63 60 return ; NO - done
64 bcf CHRG_OUT 61 ;bra charge_cv_active ; YES - charging in CV mode
65 bsf TRISJ,2 ; Chrg-Out high impedance 62
66
67 WAITMS d'1'
68
69 btfsc CHRG_IN
70 return ; Not charging, done.
71 charge_cv_active: 63 charge_cv_active:
72 decfsz get_bat_volt_counter,F 64 decfsz get_bat_volt_counter,F
73 return 65 return
74 movlw .15 66 movlw .15
75 cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4,096V)? 67 cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096V) ?
76 bra charge_cc_active ; NO 68 bra charge_cc_active ; NO
77 bsf cc_active 69 bsf cc_active
78 bsf cv_active 70 bsf cv_active
79 bsf LEDr ; indicate charging 71 bsf LEDr ; indicate charging
80 call lt2942_charge_done ; reset accumulating registers to 0xFFFF 72 call lt2942_charge_done ; reset accumulating registers to 0xFFFF
85 77
86 charge_cc_active: 78 charge_cc_active:
87 bsf cc_active 79 bsf cc_active
88 bsf LEDr ; indicate charging 80 bsf LEDr ; indicate charging
89 bcf CHRG_OUT 81 bcf CHRG_OUT
90 bsf TRISJ,2 ; chrg-Out high impedance 82 bsf TRISJ,2 ; set chrg-Out output to high impedance
91 movlw .15 83 movlw .15
92 cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096 V)? 84 cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096 V)?
93 bra charge_cc_active2 ; NO 85 bra charge_cc_active2 ; NO
94 movlw .81 86 movlw .81
95 cpfslt batt_voltage+0 ; battery voltage >= 80mV (+4096mV from batt_voltage+1)? 87 cpfslt batt_voltage+0 ; battery voltage >= 80mV (+4096mV from batt_voltage+1)?
97 charge_cc_active2: 89 charge_cc_active2:
98 movlw .10 90 movlw .10
99 movwf get_bat_volt_counter 91 movwf get_bat_volt_counter
100 return 92 return
101 93
102 get_battery_voltage1: 94 get_battery_voltage_2: ; no gauge IC available, use ADC to measure battery voltage
103 ; Additional disable in software 95 ; additional charging disable in software
104 bsf charge_disable 96 bsf charge_disable ; set charging-inhibit signal
105 bcf TRISE,2 97 bcf charge_enable ; activate charging-inhibit signal
106 bsf adc_running ; =1: The ADC is in use 98
107 99 bsf adc_is_running ; =1: the ADC is in use
108 movlw b'00100000' ; 2.048V Vref+ -> 1LSB = 500µV 100 movlw b'00100000' ; 2.048 Volt Vref+ -> 1 LSB = 500 µV
109 movwf ADCON1 101 movwf ADCON1
110 movlw b'00011001' ; power on ADC, select AN6 102 movlw b'00011001' ; power on ADC, select AN6
111 rcall wait_adc 103 rcall wait_adc
112 104
113 movff ADRESH,batt_voltage+1 ; store value 105 MOVII ADRESL,batt_voltage ; store value
114 movff ADRESL,batt_voltage+0 ; store value
115 bcf ADCON0,0 ; power off ADC 106 bcf ADCON0,0 ; power off ADC
116 107
117 ; Multiply with 2.006 to be exact here... 108 ; Multiply with 2.006 to be exact here...
118 ; bcf STATUS,C 109 ; bcf STATUS,C
119 ; rlcf xA+0,F 110 ; rlcf xA+0,F
120 ;
121 ; rlcf xA+1,F ; x2 111 ; rlcf xA+1,F ; x2
122 112 ; MOVII xA,batt_voltage ; store value
123 ; movff xA+0,batt_voltage+0 ; store value 113
124 ; movff xA+1,batt_voltage+1 114 bcf battery_is_36v ; by default assume it is a 1.5 battery
125 115 MOVII batt_voltage,sub_b ; load measured battery voltage
126 movlw LOW lithium_36v_low 116
127 movwf sub_a+0 117 ; Check if the battery is a 3.6V lithium
128 movlw HIGH lithium_36v_low 118 MOVLI lithium_36v_low,sub_a ; load threshold for 3.6 Volt lithium battery
129 movwf sub_a+1 119 call cmpU16 ; sub_a - sub_b
130 movff batt_voltage+0,sub_b+0 120 btfss neg_flag ; battery voltage > 3.6 V lithium threshold ?
131 movff batt_voltage+1,sub_b+1 121 bra get_battery_voltage_9 ; NO - keep assumption of 1.5V battery
132 call subU16 ; sub_c = sub_a - sub_b 122 bsf battery_is_36v ; YES - set flag
133 ; Battery is 3.6V (> lithium_36v_low?)
134 btfss neg_flag
135 bra get_battery_voltage4 ; NO - use 1.5V
136 bsf battery_is_36v ; YES - set flag (Cleared in power-on reset only!)
137 123
138 ; Check if the battery is near-dead already 124 ; Check if the battery is near-dead already
139 movlw LOW lithium_36v_empty 125 MOVLI lithium_36v_empty,sub_a ; load threshold for near-dead lithium battery
140 movwf sub_a+0 126 call cmpU16 ; sub_a - sub_b
141 movlw HIGH lithium_36v_empty 127 btfsc neg_flag ; battery voltage > dead-battery threshold ?
142 movwf sub_a+1 128 bra get_battery_voltage_3 ; YES - battery is still ok
143 call subU16 ; sub_c = sub_a - sub_b 129 movlw .128 ; NO - battery is probably dead very soon, set ">=24Ah used"
144 ; Battery is not dead yet (> lithium_36v_empty)? 130 movff WREG,battery_gauge+5 ; - into battery gauge registers
145 btfsc neg_flag 131
146 bra get_battery_voltage2 ; YES - battery is still ok 132 get_battery_voltage_3: ; 3.6V battery gauge mode
147 133 ; SMOVFF "by hand" as the macro does not work with arguments that have a '+something' with them
148 ; Battery is probably dead very soon 134 bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in
149 ; Set ">=24Ah used" into battery gauge registers
150 movlw .128
151 movff WREG,battery_gauge+5
152
153 get_battery_voltage2:
154 ; Use 3.6V battery gauging mode
155 movff battery_gauge+5,xC+3 135 movff battery_gauge+5,xC+3
156 movff battery_gauge+4,xC+2 136 movff battery_gauge+4,xC+2
157 movff battery_gauge+3,xC+1 137 movff battery_gauge+3,xC+1
158 movff battery_gauge+2,xC+0 138 movff battery_gauge+2,xC+0
139 btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag?
140 bra get_battery_voltage_3 ; YES - retry copy
141
159 ; battery_gauge: 6 is nAs 142 ; battery_gauge: 6 is nAs
160 ; divide through 65536 143 ; divide through 65536
161 ; divide through battery_capacity:2 144 ; divide through battery_capacity:2
162 ; result is in percent 145 ; result is in percent
163 movff internal_battery_capacity+0,xB+0 146 MOVII battery_capacity_internal,xB
164 movff internal_battery_capacity+1,xB+1
165 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder 147 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder
166 movff xC+0,lo 148 movff xC+0,lo
167 ; limit to 100 149 ; limit to 100
168 movlw .100 150 movlw .100
169 cpfslt lo 151 cpfslt lo
170 movwf lo 152 movwf lo
171 ; lo will be between 0 (full) and 100 (empty) 153 ; lo will be between 0 (full) and 100 (empty)
172 movf lo,W 154 movf lo,W
173 sublw .100 155 sublw .100
174 movwf lo 156 movwf lo
175 get_battery_voltage3: 157 get_battery_voltage_4:
176 movlw .100 158 movlw .100 ; start with default of 100%
177 cpfslt lo 159 cpfslt lo ; > 100%
160 movwf lo ; YES - limit to 100%
161 ; lo will be between 100 (full) and 0 (empty)
162 ; use 3.6V battery sensing based on 50 mA load
163 MOVLI lithium_36v_75,sub_a ; load threshold for > 75%
164 call cmpU16 ; sub_a - sub_b
165 btfsc neg_flag ; battery voltage above 75% level?
166 bra get_battery_voltage_5 ; YES
167 movlw .75 ; NO - set to 75%
178 movwf lo 168 movwf lo
179 ; lo will be between 100 (full) and 0 (empty) 169 get_battery_voltage_5:
180 170 ; 50%
181 ; use 3.6V battery sensing based on 50 mA load 171 MOVLI lithium_36v_50,sub_a ; load threshold for > 50%
182 ; 75% 172 call cmpU16 ; sub_a - sub_b
183 movff batt_voltage+0,sub_b+0 173 btfsc neg_flag ; battery voltage above 75% level?
184 movff batt_voltage+1,sub_b+1 174 bra get_battery_voltage_6 ; YES
185 movlw LOW lithium_36v_75 175 movlw .50 ; NO - set to 50%
186 movwf sub_a+0 176 movwf lo
187 movlw HIGH lithium_36v_75 177 get_battery_voltage_6:
188 movwf sub_a+1 178 ; 25%
179 MOVLI lithium_36v_25,sub_a ; load threshold for > 25%
180 call cmpU16 ; sub_a - sub_b
181 btfsc neg_flag ; battery voltage above 25% level?
182 bra get_battery_voltage_7 ; YES
183 movlw .25 ; NO - set to 25%
184 movwf lo
185 get_battery_voltage_7:
186 ; 10%
187 MOVLI lithium_36v_10,sub_a ; load threshold for > 10%
188 call cmpU16 ; sub_a - sub_b
189 btfsc neg_flag ; battery voltage above 10% level?
190 bra get_battery_voltage_8 ; YES
191 movlw .10 ; NO - set to 10%
192 movwf lo
193 get_battery_voltage_8:
194 movlw .100 ; maximum is 100 (%)
195 cpfslt lo ; > 100% ?
196 movwf lo ; YES - limit to 100%
197 movf batt_percent,W ; get last battery percentage
198 cpfsgt lo ; current battery % < last battery % ?
199 movff lo,batt_percent ; YES - take new value (keep batt_percent on the lowest value found)
200 btfsc battery_is_36v ; using a 3.6 volt battery?
201 movff lo,batt_percent ; YES - take new value (always use computed value for 3.6V battery)
202 bcf adc_is_running ; done with ADC
203 return
204
205 get_battery_voltage_9:
206 ; use 1.5V battery voltage mode
207 ; use approximation (batt_voltage-aa_15v_low)/4 = lo
208 MOVII batt_voltage,sub_a ; load battery voltage
209 MOVLI aa_15v_low, sub_b ; load offset
189 call subU16 ; sub_c = sub_a - sub_b 210 call subU16 ; sub_c = sub_a - sub_b
190 btfsc neg_flag 211 bcf STATUS,C ; shift right to divide / 2
191 bra get_battery_voltage3a
192 movlw .75
193 movwf lo
194 get_battery_voltage3a:
195 ; 50%
196 movlw LOW lithium_36v_50
197 movwf sub_a+0
198 movlw HIGH lithium_36v_50
199 movwf sub_a+1
200 call subU16 ; sub_c = sub_a - sub_b
201 btfsc neg_flag
202 bra get_battery_voltage3b
203 movlw .50
204 movwf lo
205 get_battery_voltage3b:
206 ; 25%
207 movlw LOW lithium_36v_25
208 movwf sub_a+0
209 movlw HIGH lithium_36v_25
210 movwf sub_a+1
211 call subU16 ; sub_c = sub_a - sub_b
212 btfsc neg_flag
213 bra get_battery_voltage3c
214 movlw .25
215 movwf lo
216 get_battery_voltage3c:
217 ; 10%
218 movlw LOW lithium_36v_10
219 movwf sub_a+0
220 movlw HIGH lithium_36v_10
221 movwf sub_a+1
222 call subU16 ; sub_c = sub_a - sub_b
223 btfsc neg_flag
224 bra get_battery_voltage3d
225 movlw .10
226 movwf lo
227 get_battery_voltage3d:
228 movlw .100
229 cpfslt lo
230 movwf lo
231 ; lo will be between 100 (full) and 0 (empty)
232 movf batt_percent,W
233 cpfsgt lo ; keep batt_percent on the lowest value found
234 movff lo,batt_percent ; store value
235 btfsc battery_is_36v ; but always use computed value for 3.6V battery
236 movff lo,batt_percent ; store value
237 bcf adc_running ; =1: the ADC is in use
238 return
239
240 get_battery_voltage4:
241 ; use 1.5V battery voltage mode
242 ; use approximation (batt_voltage:2-aa_15v_low)/4 = lo
243 movff batt_voltage+0,sub_a+0
244 movff batt_voltage+1,sub_a+1
245 movlw LOW aa_15v_low
246 movwf sub_b+0
247 movlw HIGH aa_15v_low
248 movwf sub_b+1
249 call subU16 ; sub_c = sub_a - sub_b
250 bcf STATUS,C
251 rrcf sub_c+1 212 rrcf sub_c+1
252 rrcf sub_c+0 ; /2 213 rrcf sub_c+0
253 bcf STATUS,C 214 bcf STATUS,C ; another shift right to divide / 4
254 rrcf sub_c+1 215 rrcf sub_c+1
255 rrcf sub_c+0 ; /4 216 rrcf sub_c+0
256 movff sub_c+0,lo 217 movff sub_c+0,lo ; store result
257 bra get_battery_voltage3d ; check limits and return 218 bra get_battery_voltage_8 ; check limits and return
258 219
259 global get_ambient_level 220
221 global get_ambient_level ; called from ISR only, in context bank isr_backup
260 get_ambient_level: ; starts ADC and waits until finished 222 get_ambient_level: ; starts ADC and waits until finished
261 btfsc adc_running ; ADC in use? 223 btfsc sleepmode ; in sleep mode?
262 return ; YES - return 224 return ; YES - done
263 225 btfsc adc_is_running ; NO - ADC in use?
264 btfsc ambient_sensor 226 return ; YES - return
265 bra get_ambient_level1 ; normal OSTC3 hardware 227 banksel HW_descriptor ; NO - select bank where hardware descriptor is stored
266 228 btfsc ambient_sensor ; - ambient sensor available?
267 banksel isr_backup ; back to bank0 ISR data 229 bra get_ambient_level1 ; YES - use sensor
268 movff opt_brightness,isr1_temp 230 banksel isr_backup ; NO - back to ISR default bank
269 incf isr1_temp,F ; adjust 0-2 to 1-3 231 movff opt_brightness,isr_lo ; - get brightness selection
270 movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting 232 incf isr_lo,F ; - 0-2 -> 1-3
271 dcfsnz isr1_temp,F 233 movlw ambient_light_max_high_cr ; - default selection to brightest setting
272 movlw ambient_light_max_eco ; brightest setting 234 dcfsnz isr_lo,F ; - level 0 (eco) selected?
273 dcfsnz isr1_temp,F 235 movlw ambient_light_max_eco ; YES - select eco brightness
274 movlw ambient_light_max_medium ; brightest setting 236 dcfsnz isr_lo,F ; - level 1 (medium) selected?
275 237 movlw ambient_light_max_medium ; YES - select medium brightness
276 movff WREG,ambient_light+0 ; set to max. 238 movwf ambient_light+0 ; - store selection
277 movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt 239 movwf max_CCPR1L ; - store value for dimming in TMR7 interrupt
278 return 240 return ; - done
279 241
280 get_ambient_level1: 242 get_ambient_level1: ; using ambient sensor
243 banksel isr_backup ; back to ISR default bank
281 movlw b'00000000' ; Vref+ = Vdd 244 movlw b'00000000' ; Vref+ = Vdd
282 movwf ADCON1 245 movwf ADCON1
283 movlw b'00011101' ; power on ADC, select AN7 246 movlw b'00011101' ; power on ADC, select AN7
284 rcall wait_adc 247 rcall wait_adc
285 248 MOVII ADRESL,ambient_light
286 movff ADRESH,ambient_light+1
287 movff ADRESL,ambient_light+0
288 bcf ADCON0,0 ; power off ADC 249 bcf ADCON0,0 ; power off ADC
289 250
290 ; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness) 251 ; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness)
291 ; first: divide by 16 252 ; first: divide by 16
292 banksel ambient_light
293 bcf STATUS,C 253 bcf STATUS,C
294 rrcf ambient_light+1 254 rrcf ambient_light+1
295 rrcf ambient_light+0 255 rrcf ambient_light+0
296 bcf STATUS,C 256 bcf STATUS,C
297 rrcf ambient_light+1 257 rrcf ambient_light+1
319 ; movlw .10 279 ; movlw .10
320 ; subwf ambient_light+0,F ; subtract 10 (ADC Offset) 280 ; subwf ambient_light+0,F ; subtract 10 (ADC Offset)
321 ; btfsc STATUS,N 281 ; btfsc STATUS,N
322 ; movwf ambient_light+0 ; avoid clipping 282 ; movwf ambient_light+0 ; avoid clipping
323 283
324 banksel isr_backup ; back to bank0 ISR data 284 movff opt_brightness,isr_lo ; get brightness setting
325 movff opt_brightness,isr1_temp
326 285
327 btfsc RCSTA1,7 ; UART module on? 286 btfsc RCSTA1,7 ; UART module on?
328 clrf isr1_temp ; YES - set temporally to eco mode 287 clrf isr_lo ; YES - set temporary to eco mode
329 288 incf isr_lo,F ; adjust 0-2 to 1-3
330 incf isr1_temp,F ; adjust 0-2 to 1-3 289
331
332 banksel common ; flag is in bank1
333 movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting 290 movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting
291
292 banksel HW_descriptor ; select bank where hardware descriptor and model variant is stored
334 btfss battery_gauge_available 293 btfss battery_gauge_available
335 movlw ambient_light_max_high_15V ; 1.5V battery brightest setting 294 movlw ambient_light_max_high_15V ; 1.5V battery brightest setting
336 btfsc battery_is_36v ; 3.6V battery in use? 295 btfsc battery_is_36v ; 3.6V battery in use?
337 movlw ambient_light_max_high_36V ; YES - 3.6V battery brightest setting 296 movlw ambient_light_max_high_36V ; YES - 3.6V battery brightest setting
338 banksel isr_backup ; back to bank0 ISR data 297 banksel isr_backup ; back to ISR default bank
339 298
340 dcfsnz isr1_temp,F 299 dcfsnz isr_lo,F
341 movlw ambient_light_max_eco ; brightest setting 300 movlw ambient_light_max_eco ; eco setting
342 dcfsnz isr1_temp,F 301 dcfsnz isr_lo,F
343 movlw ambient_light_max_medium ; brightest setting 302 movlw ambient_light_max_medium ; brightest setting
344 303
345 banksel ambient_light
346 incf ambient_light+0,F ; +1 304 incf ambient_light+0,F ; +1
347 cpfslt ambient_light+0 ; smaller than WREG? 305 cpfslt ambient_light+0 ; smaller than WREG?
348 movwf ambient_light+0 ; NO - set to max. 306 movwf ambient_light+0 ; NO - set to max.
349 307
350 banksel isr_backup ; back to bank0 ISR data 308 movff opt_brightness,isr_lo
351 movff opt_brightness,isr1_temp 309 incf isr_lo,F ; adjust 0-2 to 1-3
352 incf isr1_temp,F ; adjust 0-2 to 1-3
353 movlw ambient_light_min_high ; darkest setting 310 movlw ambient_light_min_high ; darkest setting
354 311 dcfsnz isr_lo,F
355 dcfsnz isr1_temp,F
356 movlw ambient_light_min_eco ; darkest setting 312 movlw ambient_light_min_eco ; darkest setting
357 dcfsnz isr1_temp,F 313 dcfsnz isr_lo,F
358 movlw ambient_light_min_medium ; darkest setting 314 movlw ambient_light_min_medium ; darkest setting
359 dcfsnz isr1_temp,F 315 dcfsnz isr_lo,F
360 movlw ambient_light_min_high ; darkest setting 316 movlw ambient_light_min_high ; darkest setting
361 317
362 banksel ambient_light
363 cpfsgt ambient_light+0 ; bigger than WREG? 318 cpfsgt ambient_light+0 ; bigger than WREG?
364 movwf ambient_light+0 ; NO - set to min 319 movwf ambient_light+0 ; NO - set to min
365 banksel common
366 320
367 movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt 321 movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt
368 return 322 return
369 323
370 global get_analog_inputs 324
325 ;=============================================================================
326 ; routines for reading analog-attached external sensors
327 ;
328 IFDEF _external_sensor
329
330 global get_analog_inputs ; called from outside ISR only
371 get_analog_inputs: ; start ADC and wait until finished 331 get_analog_inputs: ; start ADC and wait until finished
372 bsf adc_running ; =1: The ADC is in use 332 bsf adc_is_running ; =1: the ADC is in use
373 btfsc TFT_PWM 333 btfsc TFT_PWM
374 bra get_analog_inputs ; wait for PWM low 334 bra get_analog_inputs ; wait for PWM low
375 movlw b'00100000' ; 2.048V Vref+ -> 1 LSB = 500 µV 335 movlw b'00100000' ; 2.048V Vref+ -> 1 LSB = 500 µV
376 movwf ADCON1 336 movwf ADCON1
337 banksel sensor1_mv ; select bank where sensor1_mv is stored
338 ; Sensor 1
377 movlw b'00100001' ; power on ADC, select AN8 339 movlw b'00100001' ; power on ADC, select AN8
378 rcall wait_adc 340 rcall wait_adc
379 bcf STATUS,C 341 bcf STATUS,C
380 rrcf ADRESH,F ; /2 342 rrcf ADRESH,F ; /2
381 rrcf ADRESL,W 343 rrcf ADRESL,W
382 ; add to o2_mv_sensor1:2 344 addwf sensor1_mv+0,F ; add to sensor1_mv:2
383 addwf o2_mv_sensor1+0,F
384 movf ADRESH,W 345 movf ADRESH,W
385 addwfc o2_mv_sensor1+1,F 346 addwfc sensor1_mv+1,F
386 ; divide by 2 347 bcf STATUS,C
387 bcf STATUS,C 348 rrcf sensor1_mv+1,F ; divide /2
388 rrcf o2_mv_sensor1+1,F ; /2 349 rrcf sensor1_mv+0,F
389 rrcf o2_mv_sensor1+0,F
390
391 movlw HIGH ignore_mv 350 movlw HIGH ignore_mv
392 cpfsgt o2_mv_sensor1+1 ; > ignore_mv ? 351 cpfsgt sensor1_mv+1 ; > ignore_mv ?
393 bra get_analog_inputs2a ; NO 352 bra get_analog_inputs1a ; NO
394 ; YES - ignore this reading 353 CLRI sensor1_mv ; YES - ignore this reading
395 clrf o2_mv_sensor1+1 354 get_analog_inputs1a: ; ignore 1.9 mV noise for not-connected inputs
396 clrf o2_mv_sensor1+0 355 tstfsz sensor1_mv+1 ; > 25.5 mV ?
397 get_analog_inputs2a:
398 ; ignore 1.9 mV noise for not-connected inputs
399 tstfsz o2_mv_sensor1+1 ; > 25.5mV ?
400 bra get_analog_inputs2 ; YES - skip here 356 bra get_analog_inputs2 ; YES - skip here
401 movlw .19 357 movlw .19
402 cpfsgt o2_mv_sensor1+0 ; > 1.9mV ? 358 cpfsgt sensor1_mv+0 ; > 1.9 mV ?
403 clrf o2_mv_sensor1+0 ; NO - clear result 359 clrf sensor1_mv+0 ; NO - clear result
360
404 get_analog_inputs2: 361 get_analog_inputs2:
362 ; Sensor 2
405 movlw b'00100101' ; power on ADC, select AN9 363 movlw b'00100101' ; power on ADC, select AN9
406 rcall wait_adc 364 rcall wait_adc
407 bcf STATUS,C 365 bcf STATUS,C
408 rrcf ADRESH,F ; /2 366 rrcf ADRESH,F ; /2
409 rrcf ADRESL,W 367 rrcf ADRESL,W
410 ; add to o2_mv_sensor2:2 368 addwf sensor2_mv+0,F ; add to sensor2_mv:2
411 addwf o2_mv_sensor2+0,F
412 movf ADRESH,W 369 movf ADRESH,W
413 addwfc o2_mv_sensor2+1,F 370 addwfc sensor2_mv+1,F
414 ; divide by 2 371 bcf STATUS,C
415 bcf STATUS,C 372 rrcf sensor2_mv+1,F ; divide /2
416 rrcf o2_mv_sensor2+1,F ; /2 373 rrcf sensor2_mv+0,F
417 rrcf o2_mv_sensor2+0,F
418
419 movlw HIGH ignore_mv 374 movlw HIGH ignore_mv
420 cpfsgt o2_mv_sensor2+1 ; > ignore_mv ? 375 cpfsgt sensor2_mv+1 ; > ignore_mv ?
421 bra get_analog_inputs3a ; NO 376 bra get_analog_inputs2a ; NO
422 ; YES - ignore this reading 377 CLRI sensor2_mv ; YES - ignore this reading
423 clrf o2_mv_sensor2+1 378 get_analog_inputs2a: ; ignore 1.9 mV noise for not-connected inputs
424 clrf o2_mv_sensor2+0 379 tstfsz sensor2_mv+1 ; > 25.5 mV ?
425 get_analog_inputs3a:
426 ; ignore 1.9 mV noise for not-connected inputs
427 tstfsz o2_mv_sensor2+1 ; > 25.5 mV ?
428 bra get_analog_inputs3 ; YES - skip here 380 bra get_analog_inputs3 ; YES - skip here
429 movlw .19 381 movlw .19
430 cpfsgt o2_mv_sensor2+0 ; > 1.9 mV ? 382 cpfsgt sensor2_mv+0 ; > 1.9 mV ?
431 clrf o2_mv_sensor2+0 ; NO - clear result 383 clrf sensor2_mv+0 ; NO - clear result
384
432 get_analog_inputs3: 385 get_analog_inputs3:
386 ; Sensor 3
433 movlw b'00101001' ; power on ADC, select AN10 387 movlw b'00101001' ; power on ADC, select AN10
434 rcall wait_adc 388 rcall wait_adc
435 bcf STATUS,C 389 bcf STATUS,C
436 rrcf ADRESH,F ; /2 390 rrcf ADRESH,F ; /2
437 rrcf ADRESL,W 391 rrcf ADRESL,W
438 ; add to o2_mv_sensor3:2 392 addwf sensor3_mv+0,F ; add to sensor3_mv:2
439 addwf o2_mv_sensor3+0,F
440 movf ADRESH,W 393 movf ADRESH,W
441 addwfc o2_mv_sensor3+1,F 394 addwfc sensor3_mv+1,F
442 ; divide by 2 395 bcf STATUS,C
443 bcf STATUS,C 396 rrcf sensor3_mv+1,F ; divide /2
444 rrcf o2_mv_sensor3+1,F ; /2 397 rrcf sensor3_mv+0,F
445 rrcf o2_mv_sensor3+0,F
446
447 movlw HIGH ignore_mv 398 movlw HIGH ignore_mv
448 cpfsgt o2_mv_sensor3+1 ; > ignore_mv ? 399 cpfsgt sensor3_mv+1 ; > ignore_mv ?
449 bra get_analog_inputs4a ; NO 400 bra get_analog_inputs3a ; NO
450 ; YES - ignore this reading 401 CLRI sensor3_mv ; YES - ignore this reading
451 clrf o2_mv_sensor3+1 402 get_analog_inputs3a: ; ignore 1.9 mV noise for not-connected inputs
452 clrf o2_mv_sensor3+0 403 tstfsz sensor3_mv+1 ; > 25.5 mV ?
453 get_analog_inputs4a:
454 ; ignore 1.9mV noise for not-connected inputs
455 tstfsz o2_mv_sensor3+1 ; > 25.5 mV ?
456 bra get_analog_inputs4 ; YES - skip here 404 bra get_analog_inputs4 ; YES - skip here
457 movlw .19 405 movlw .19
458 cpfsgt o2_mv_sensor3+0 ; > 1.9 mV ? 406 cpfsgt sensor3_mv+0 ; > 1.9 mV ?
459 clrf o2_mv_sensor3+0 ; NO - clear result 407 clrf sensor3_mv+0 ; NO - clear result
460 get_analog_inputs4: 408 get_analog_inputs4:
409 banksel common ; back to bank common
461 bcf ADCON0,0 ; power off ADC 410 bcf ADCON0,0 ; power off ADC
462 bcf adc_running ; =1: the ADC is in use 411 bcf adc_is_running ; done with ADC
463 return 412 return
464 413
465 global piezo_config ; set up piezo sensitivity of heinrichs weikamp piezo buttons (~30ms) 414 ENDIF ; _external_sensor
466 piezo_config: ; settings between 20 and 200 415
467 clrf TMR5H 416 ;=============================================================================
468 clrf TMR5L ; ~2sec 417
469 bcf PIR5,TMR5IF ; clear flag 418 global piezo_config ; called from outside ISR only
470 bcf switch_right 419 piezo_config: ; set up sensitivity of heinrichsweikamp piezo buttons (~30ms)
471 bcf switch_left 420 clrf TMR5H ; clear TMR5H first
421 clrf TMR5L ; clear TMR5L thereafter
422 bcf PIR5,TMR5IF ; clear timer 5 overrun flag, will take ~ 2 seconds to overrun after reset
423 bcf switch_right ; clear left-over button events
424 bcf switch_left ; ...
472 piezo_config0: 425 piezo_config0:
473 btfsc switch_right 426 btfsc switch_right ; user still pressing the right button?
474 bra piezo_config 427 bra piezo_config ; YES - loop to wait for release
475 btfsc switch_left 428 btfsc switch_left ; user still pressing the left button?
476 bra piezo_config ; restart on button press 429 bra piezo_config ; YES - loop to wait for release
477 430
478 btfss PIR5,TMR5IF 431 btfss PIR5,TMR5IF ; timeout?
479 bra piezo_config0 ; wait loop 432 bra piezo_config0 ; NO - not yet, loop
480 433
481 bcf INTCON,GIE 434 bcf INTCON,GIE
482 435
483 movff opt_cR_button_right,WREG ; right button 436 movff opt_cR_button_right,WREG ; right button
484 btfsc flip_screen ; 180° rotation ? 437 btfsc flip_screen ; 180° rotation ?
516 bsf TX3_PIEZO_CFG ; stop bit 469 bsf TX3_PIEZO_CFG ; stop bit
517 rcall piezo_config_wait_bit 470 rcall piezo_config_wait_bit
518 return 471 return
519 472
520 piezo_config_wait_bit: 473 piezo_config_wait_bit:
521 setf TMR5H 474 setf TMR5H ; set TMR5H first (to 255)
522 movlw .255-.26 ; 26 x 31,5µs = 819us 475 movlw .255-.26 ; 26 x 31.5 µs = 819 us
523 movwf TMR5L 476 movwf TMR5L ; set TMR5L thereafter
524 bcf PIR5,TMR5IF ; clear flag 477 bcf PIR5,TMR5IF ; clear timer 5 overrun flag
525 piezo_config_wait_bit3: 478 piezo_config_wait_bit3:
526 btfss PIR5,TMR5IF 479 btfss PIR5,TMR5IF ; timeout?
527 bra piezo_config_wait_bit3 ; wait loop 480 bra piezo_config_wait_bit3 ; NO - loop
528 return 481 return ; YES - done
529 482
530 global reset_battery_pointer 483
531 reset_battery_pointer: ; reset battery pointer 0x07-0x0C and battery_gauge:5 484 global get_analog_switches ; called from ISR and from sleep mode, returns in bank common
532 extern lt2942_charge_done
533 btfsc battery_gauge_available ; something to reset?
534 call lt2942_charge_done ; YES - reset accumulating registers to 0xFFFF
535 goto reset_battery_internal_only ; and return
536
537
538 global get_analog_switches
539 get_analog_switches: ; start ADC and wait until finished 485 get_analog_switches: ; start ADC and wait until finished
486 banksel HW_variants ; switch to bank where OSTC model variant is stored
540 btfsc analog_switches ; does the OSTC have analog switches? 487 btfsc analog_switches ; does the OSTC have analog switches?
541 bra get_analog_switches2 ; YES 488 bra get_analog_switches_1 ; YES
542 ; NO 489 banksel common ; NO - back to bank common
543 bcf analog_sw1_pressed ; NO - clear flag for analog switch 1 490 bcf analog_sw1_pressed ; - clear flag for analog switch 1
544 bcf analog_sw2_pressed ; - clear flag for analog switch 2 491 bcf analog_sw2_pressed ; - clear flag for analog switch 2
545 return ; - done 492 return ; - done
546 get_analog_switches2: 493
547 btfsc adc_running ; ADC in use? 494 get_analog_switches_1:
495 banksel common ; back to bank common
496 btfsc adc_is_running ; ADC in use?
548 return ; YES - abort 497 return ; YES - abort
549 ; NO 498 ;bra get_analog_switches_2 ; NO - read switches
499
500 get_analog_switches_2:
550 movlw b'00001001' ; left justified 501 movlw b'00001001' ; left justified
551 movwf ADCON2 502 movwf ADCON2
552 ; movlw b'00000000' ; Vref+ = Vdd 503 ; movlw b'00000000' ; Vref+ = Vdd
553 clrf ADCON1 504 clrf ADCON1
554 movlw b'00100101' ; power on ADC, select AN9 505 movlw b'00100101' ; power on ADC, select AN9
555 rcall wait_adc 506 rcall wait_adc
556 banksel analog_counter 507
508 banksel isr_backup ; select bank ISR data
557 movff ADRESH,WREG 509 movff ADRESH,WREG
558 addwf analog_sw2_raw+0 510 addwf analog_sw2_raw+0
559 movlw .0 511 movlw .0
560 addwfc analog_sw2_raw+1 512 addwfc analog_sw2_raw+1
561 decfsz analog_counter,F ; continue averaging? 513 decfsz analog_counter,F ; continue averaging?
562 bra get_analog_switches2a ; YES 514 bra get_analog_switches_2a ; YES
563 ; NO - done, compute average 515 bcf STATUS,C ; NO - done, compute average
564 bcf STATUS,C
565 rrcf analog_sw2_raw+1 516 rrcf analog_sw2_raw+1
566 rrcf analog_sw2_raw+0 ; /2 517 rrcf analog_sw2_raw+0 ; /2
567 bcf STATUS,C 518 bcf STATUS,C
568 rrcf analog_sw2_raw+1 519 rrcf analog_sw2_raw+1
569 rrcf analog_sw2_raw+0 ; /4 520 rrcf analog_sw2_raw+0 ; /4
576 movff analog_sw2_raw+0,analog_sw2 527 movff analog_sw2_raw+0,analog_sw2
577 clrf analog_sw2_raw+1 528 clrf analog_sw2_raw+1
578 clrf analog_sw2_raw+0 ; reset average registers 529 clrf analog_sw2_raw+0 ; reset average registers
579 ; movlw .16 530 ; movlw .16
580 ; movwf analog_counter ; only once... 531 ; movwf analog_counter ; only once...
581 get_analog_switches2a: 532
582 banksel common 533 get_analog_switches_2a:
583 bcf analog_sw2_pressed 534 bcf analog_sw2_pressed ; default to not pressed
584 movff opt_cR_button_left,WREG ; 20-100 535 movff opt_cR_button_left,WREG ; 20-100
585 bcf STATUS,C 536 bcf STATUS,C
586 rrcf WREG ; /2 -> 10-50 537 rrcf WREG ; /2 -> 10-50
587 bcf STATUS,C 538 bcf STATUS,C
588 rrcf WREG ; /2 -> 5-25 539 rrcf WREG ; /2 -> 5-25
589 decf WREG,W ; -1 540 decf WREG,W ; -1
590 decf WREG,W ; -1 541 decf WREG,W ; -1
591 decf WREG,W ; -1 -> 2-22 542 decf WREG,W ; -1 -> 2-22
592 banksel analog_sw2
593 btfss button_polarity,1 ; (1= normal, 0=inverted) 543 btfss button_polarity,1 ; (1= normal, 0=inverted)
594 bra sw2_inverted 544 bra get_analog_switches_sw2_inv
595 addwf analog_sw2,W ; average (~128) 545 addwf analog_sw2,W ; average (~128)
596 cpfsgt ADRESH 546 cpfsgt ADRESH ; pressed?
597 bra get_analog_sw1 547 bra get_analog_switches_3 ; NO
598 banksel common 548 bra get_analog_switches_sw2_pressed ; YES (left button normal)
599 bsf analog_sw2_pressed ; left button normal 549
600 bra get_analog_sw1 550 get_analog_switches_sw2_inv:
601 sw2_inverted:
602 subwf analog_sw2,W ; average (~128) 551 subwf analog_sw2,W ; average (~128)
603 cpfslt ADRESH 552 cpfslt ADRESH ; pressed?
604 bra get_analog_sw1 553 bra get_analog_switches_3 ; NO
605 banksel common 554 ;bra get_analog_switches_sw2_pressed ; YES (left button inverted)
606 bsf analog_sw2_pressed ; left button inverted 555
607 get_analog_sw1: 556 get_analog_switches_sw2_pressed:
608 banksel common 557 bsf analog_sw2_pressed ; set left button as pressed
558
559 get_analog_switches_3:
609 movlw b'00101001' ; power on ADC, select AN10 560 movlw b'00101001' ; power on ADC, select AN10
610 rcall wait_adc 561 rcall wait_adc
611 banksel analog_counter
612 movff ADRESH,WREG 562 movff ADRESH,WREG
613 addwf analog_sw1_raw+0 563 addwf analog_sw1_raw+0
614 movlw .0 564 movlw .0
615 addwfc analog_sw1_raw+1 565 addwfc analog_sw1_raw+1
616 tstfsz analog_counter ; continue averaging? 566 tstfsz analog_counter ; continue averaging?
617 bra get_analog_switches1a ; YES 567 bra get_analog_switches_3a ; YES
618 ; NO - done, compute average 568 bcf STATUS,C ; NO - done, compute average
619 bcf STATUS,C
620 rrcf analog_sw1_raw+1 569 rrcf analog_sw1_raw+1
621 rrcf analog_sw1_raw+0 ; /2 570 rrcf analog_sw1_raw+0 ; /2
622 bcf STATUS,C 571 bcf STATUS,C
623 rrcf analog_sw1_raw+1 572 rrcf analog_sw1_raw+1
624 rrcf analog_sw1_raw+0 ; /4 573 rrcf analog_sw1_raw+0 ; /4
631 movff analog_sw1_raw+0,analog_sw1 580 movff analog_sw1_raw+0,analog_sw1
632 clrf analog_sw1_raw+1 581 clrf analog_sw1_raw+1
633 clrf analog_sw1_raw+0 ; reset average registers 582 clrf analog_sw1_raw+0 ; reset average registers
634 movlw .16 583 movlw .16
635 movwf analog_counter ; only once... 584 movwf analog_counter ; only once...
636 get_analog_switches1a: 585
637 banksel common 586 get_analog_switches_3a:
638 bcf analog_sw1_pressed 587 bcf analog_sw1_pressed ; default to not pressed
639 movff opt_cR_button_right,WREG ; 20-100 588 movff opt_cR_button_right,WREG ; 20-100
640 bcf STATUS,C 589 bcf STATUS,C
641 rrcf WREG ; /2 -> 10-50 590 rrcf WREG ; /2 -> 10-50
642 bcf STATUS,C 591 bcf STATUS,C
643 rrcf WREG ; /2 -> 5-25 592 rrcf WREG ; /2 -> 5-25
644 decf WREG,W ; -1 593 decf WREG,W ; -1
645 decf WREG,W ; -1 594 decf WREG,W ; -1
646 decf WREG,W ; -1 -> 2-22 595 decf WREG,W ; -1 -> 2-22
647 banksel analog_sw1
648 btfss button_polarity,0 ; (1= normal, 0=inverted) 596 btfss button_polarity,0 ; (1= normal, 0=inverted)
649 bra sw1_inverted 597 bra get_analog_switches_sw1_inv
650 addwf analog_sw1,W ; average (~128) 598 addwf analog_sw1,W ; average (~128)
651 cpfsgt ADRESH 599 cpfsgt ADRESH ; pressed?
652 bra get_analog_sw_done 600 bra get_analog_switches_4 ; NO
653 banksel common 601 bra get_analog_switches_sw1_pressed ; YES (right button normal)
654 bsf analog_sw1_pressed ; right button normal 602
655 bra get_analog_sw_done 603 get_analog_switches_sw1_inv:
656 sw1_inverted:
657 subwf analog_sw1,W ; average (~128) 604 subwf analog_sw1,W ; average (~128)
658 cpfslt ADRESH 605 cpfslt ADRESH ; pressed?
659 bra get_analog_sw_done 606 bra get_analog_switches_4 ; NO
660 banksel common 607 ;bra get_analog_switches_sw1_pressed ; YES (right button inverted)
661 bsf analog_sw1_pressed ; right button inverted 608
662 get_analog_sw_done: 609 get_analog_switches_sw1_pressed:
663 banksel common 610 bsf analog_sw1_pressed ; set right button as pressed
611
612 get_analog_switches_4:
664 movlw b'10001101' ; restore to right justified 613 movlw b'10001101' ; restore to right justified
665 movwf ADCON2 614 movwf ADCON2
666 btfsc analog_sw1_pressed 615
667 return 616 banksel common ; back to bank common
668 btfsc analog_sw2_pressed 617 btfsc analog_sw1_pressed ; right button pressed?
669 return 618 return ; YES - done
670 setf TMR1H ; no button pressed, enhance timer1 to overflow quickly 619 btfsc analog_sw2_pressed ; left button pressed?
620 return ; YES - done
621 setf TMR1H ; NO to both - no button pressed, set timer1 to overflow quickly
671 return 622 return
672 623
673 END 624 END