comparison src/adc_lightsensor.asm @ 0:11d4fc797f74

init
author heinrichsweikamp
date Wed, 24 Apr 2013 19:22:45 +0200
parents
children 0e1723f2761e
comparison
equal deleted inserted replaced
-1:000000000000 0:11d4fc797f74
1 ;=============================================================================
2 ;
3 ; File adc.asm
4 ;
5 ;
6 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
7 ;=============================================================================
8 ; HISTORY
9 ; 2011-08-08 : [mH] moving from OSTC code
10
11 #include "ostc3.inc"
12 #include "math.inc"
13 #include "wait.inc"
14 #include "eeprom_rs232.inc"
15
16 sensors CODE
17
18 wait_adc:
19 movwf ADCON0
20 nop
21 bsf ADCON0,1 ; start ADC
22 wait_adc2:
23 btfsc ADCON0,1 ; Wait...
24 bra wait_adc2
25 return
26
27 global get_battery_voltage
28 get_battery_voltage: ; starts ADC and waits until fnished
29 bsf adc_running ; =1: The ADC is in use
30 movlw b'00100000' ; 2.048V Vref+ -> 1LSB = 500µV
31 movwf ADCON1
32 movlw b'00011001' ; power on ADC, select AN6
33 rcall wait_adc
34
35 movff ADRESH,batt_voltage+1 ; store value
36 movff ADRESL,batt_voltage+0 ; store value
37 bcf ADCON0,0 ; power off ADC
38
39 ; Multiply with 2,006 to be excact here...
40 ; bcf STATUS,C
41 ; rlcf xA+0,F
42 ;
43 ; rlcf xA+1,F ; x2
44
45 ; movff xA+0,batt_voltage+0 ; store value
46 ; movff xA+1,batt_voltage+1
47
48 movlw LOW lithium_36v_low
49 movwf sub_a+0
50 movlw HIGH lithium_36v_low
51 movwf sub_a+1
52 movff batt_voltage+0,sub_b+0
53 movff batt_voltage+1,sub_b+1
54 call subU16 ; sub_c = sub_a - sub_b
55 ; Battery is 3,6V (>lithium_36v_low?)
56 btfss neg_flag
57 bra get_battery_voltage4 ; No, use 1,5V
58
59 bsf battery_is_36v ; Yes, set flag (Cleared in power-on reset only!)
60
61 ; Check if the battery is near-dead already
62 movlw LOW lithium_36v_empty
63 movwf sub_a+0
64 movlw HIGH lithium_36v_empty
65 movwf sub_a+1
66 call subU16 ; sub_c = sub_a - sub_b
67 ; Battery is not dead yet (>lithium_36v_empty?)
68 btfsc neg_flag
69 bra get_battery_voltage2 ; Yes, battery is still ok
70
71 ; Battery is probably dead very soon
72 ; Set ">=24Ah used" into battery gauge registers
73 movlw .128
74 movff WREG,battery_gauge+5
75
76 get_battery_voltage2:
77 ; Use 3,6V battery gauging mode
78 movff battery_gauge+5,xC+3
79 movff battery_gauge+4,xC+2
80 movff battery_gauge+3,xC+1
81 movff battery_gauge+2,xC+0
82 ; battery_gauge:6 is nAs
83 ; devide through 65536
84 ; devide through 364
85 ; Result is in percent of a 2,4Ah Battery
86 movlw LOW .364
87 movwf xB+0
88 movlw HIGH .364
89 movwf xB+1
90 call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
91 movff xC+0,lo
92 ; Limit to 100
93 movlw .100
94 cpfslt lo
95 movwf lo
96 ; lo will be between 0 (Full) and 100 (empty)
97 movf lo,W
98 sublw .100
99 movwf lo
100 get_battery_voltage3:
101 movlw .100
102 cpfslt lo
103 movwf lo
104 ; lo will be between 100 (Full) and 0 (empty)
105 movf batt_percent,W
106 cpfsgt lo ; keep batt_percent on the lowest value found
107 movff lo,batt_percent ; store value
108 btfsc battery_is_36v ; but always use computed value for 3,6V battery
109 movff lo,batt_percent ; store value
110 bcf adc_running ; =1: The ADC is in use
111 return
112
113 get_battery_voltage4:
114 ; Use 1,5V battery voltage mode
115 ; Use approximation (batt_voltage:2-aa_15v_low)/4 = lo
116 movff batt_voltage+0,sub_a+0
117 movff batt_voltage+1,sub_a+1
118 movlw LOW aa_15v_low
119 movwf sub_b+0
120 movlw HIGH aa_15v_low
121 movwf sub_b+1
122 call subU16 ; sub_c = sub_a - sub_b
123 bcf STATUS,C
124 rrcf sub_c+1
125 rrcf sub_c+0 ; /2
126 bcf STATUS,C
127 rrcf sub_c+1
128 rrcf sub_c+0 ; /4
129 movff sub_c+0,lo
130 bra get_battery_voltage3 ; Check limits and return
131
132 global get_ambient_level
133 get_ambient_level: ; starts ADC and waits until finished
134 btfsc adc_running ; ADC in use?
135 return ; Yes, return
136
137 movlw b'00000000' ; Vref+ = Vdd
138 movwf ADCON1
139 movlw b'00011101' ; power on ADC, select AN7
140 rcall wait_adc
141
142 movff ADRESH,ambient_light+1
143 movff ADRESL,ambient_light+0
144 bcf ADCON0,0 ; power off ADC
145
146 ; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness)
147 ; First: Devide through 16
148 bcf STATUS,C
149 rrcf ambient_light+1
150 rrcf ambient_light+0
151 bcf STATUS,C
152 rrcf ambient_light+1
153 rrcf ambient_light+0
154 bcf STATUS,C
155 rrcf ambient_light+1
156 rrcf ambient_light+0
157 bcf STATUS,C
158 rrcf ambient_light+1
159 rrcf ambient_light+0
160 ; Result: ambient_light:2/16
161 ; Now, make sure to have value between ambient_light_low and ambient_light_max
162
163 movlw .254
164 tstfsz ambient_light+1 ; >255?
165 movwf ambient_light+0 ; avoid ADC clipping
166
167 incfsz ambient_light+0,W ; =255?
168 bra get_ambient_level2 ; No, continue
169
170 movlw .254
171 movwf ambient_light+0 ; avoid ADC clipping
172
173 get_ambient_level2:
174 banksel isr_backup ; Back to Bank0 ISR data
175 movff opt_brightness,isr1_temp
176
177 btfsc RCSTA1,7 ; UART module on?
178 clrf isr1_temp ; Yes, set temporally to eco mode
179
180 incf isr1_temp,F ; adjust 0-2 to 1-3
181
182 banksel common ; flag is in bank1
183 movlw ambient_light_max_high ; brightest setting
184 btfsc battery_is_36v ; 3,6V battery in use?
185 movlw ambient_light_max_high_36V ; Yes...
186 banksel isr_backup ; Back to Bank0 ISR data
187
188 dcfsnz isr1_temp,F
189 movlw ambient_light_max_eco ; brightest setting
190 dcfsnz isr1_temp,F
191 movlw ambient_light_max_medium; brightest setting
192
193 banksel common ; ambient_light is in Bank1
194 incf ambient_light+0,F ; +1
195 cpfslt ambient_light+0 ; smaller then WREG?
196 movwf ambient_light+0 ; No, set to max.
197
198 banksel isr_backup ; Back to Bank0 ISR data
199 movff opt_brightness,isr1_temp
200 incf isr1_temp,F ; adjust 0-2 to 1-3
201 movlw ambient_light_min_high ; darkest setting
202
203 dcfsnz isr1_temp,F
204 movlw ambient_light_min_eco ; darkest setting
205 dcfsnz isr1_temp,F
206 movlw ambient_light_min_medium; darkest setting
207 dcfsnz isr1_temp,F
208 movlw ambient_light_min_high ; darkest setting
209
210 banksel common ; ambient_light is in Bank1
211 cpfsgt ambient_light+0 ; bigger then WREG?
212 movwf ambient_light+0 ; No, set to min
213
214 movff ambient_light+0,max_CCPR1L ; Store value for dimming in TMR7 interrupt
215 return
216
217 global get_rssi_level
218 get_rssi_level: ; starts ADC and waits until fnished
219 bsf adc_running ; =1: The ADC is in use
220 movlw b'00100000' ; 2.048V Vref+
221 movwf ADCON1
222 movlw b'01000101' ; power on ADC, select AN17
223 rcall wait_adc
224
225 movff ADRESL,rssi_value
226 bcf ADCON0,0 ; power off ADC
227 bcf adc_running ; =1: The ADC is in use
228 return
229
230 global reset_battery_pointer
231 reset_battery_pointer: ; Resets battery pointer 0x07-0x0C and battery_gauge:5
232 clrf EEADRH
233 clrf EEDATA ; Delete to zero
234 write_int_eeprom 0x07
235 write_int_eeprom 0x08
236 write_int_eeprom 0x09
237 write_int_eeprom 0x0A
238 write_int_eeprom 0x0B
239 write_int_eeprom 0x0C
240 banksel battery_gauge+0
241 clrf battery_gauge+0
242 clrf battery_gauge+1
243 clrf battery_gauge+2
244 clrf battery_gauge+3
245 clrf battery_gauge+4
246 clrf battery_gauge+5
247 banksel common
248 movlw .100
249 movwf batt_percent
250 return
251
252
253 END