Mercurial > public > hwos_code
annotate src/i2c.asm @ 282:7d9edd3b8c86
Make a more compact COMPASS calibration code (<7KB), and add more tests.
author | jDG |
---|---|
date | Fri, 22 May 2015 14:50:40 +0200 |
parents | 653a3ab08062 |
children | ceb1b7329dce |
rev | line source |
---|---|
0 | 1 ;============================================================================= |
2 ; | |
3 ; File i2c.asm | |
4 ; | |
5 ; I2C Interface to HMC5883L and MMA8452Q | |
6 ; | |
7 ; HMC5883L's read address (8-Bit): 0x3D | |
8 ; HMC5883L's write address (8-Bit): 0x3C | |
9 ; | |
10 ; MMA8452Q's read address (8-Bit): 0x39 | |
11 ; MMA8452Q's write address (8-Bit): 0x38 | |
12 ; | |
13 ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. | |
14 ;============================================================================= | |
15 ; HISTORY | |
16 ; 2012-08-22 : [mH] Creation | |
17 | |
18 | |
275 | 19 #include "hwos.inc" ; Mandatory header |
0 | 20 #include "wait.inc" |
113 | 21 #include "math.inc" |
22 | |
200 | 23 #DEFINE battery_offset .29065 ; 65536-(3,1Ah/0,085mAh) |
24 #DEFINE battery_devider .365 ; 3,1Ah/0,085mAh/100 [%] | |
0 | 25 |
26 i2c CODE | |
27 | |
28 WaitMSSP: | |
29 decfsz i2c_temp,F ; check for timeout during I2C action | |
30 bra WaitMSSP2 | |
31 bra I2CFail ; timeout occured | |
32 WaitMSSP2: | |
33 btfss PIR1,SSPIF | |
34 bra WaitMSSP | |
35 clrf i2c_temp | |
36 bcf PIR1,SSPIF | |
37 nop | |
38 return | |
39 | |
40 I2C_WaitforACK: | |
41 btfss SSPCON2,ACKSTAT ; checks for ACK bit from slave | |
42 return | |
43 I2CFail: | |
44 rcall I2CReset ; I2C Reset | |
45 bcf PIR1,SSPIF | |
46 clrf i2c_temp | |
47 return | |
48 | |
49 I2CReset: ; Something went wrong (Slave holds SDA low?) | |
50 clrf SSP1CON1 ; wake-up slave and reset entire module | |
51 clrf SSP1CON2 | |
52 clrf SSP1STAT | |
53 bcf TRISC,3 ; SCL OUTPUT | |
54 bsf TRISC,4 ; SDA Input | |
55 bcf PORTC,3 | |
56 movlw d'9' | |
57 movwf i2c_temp ; clock-out 9 clock cycles manually | |
58 I2CReset_1: | |
59 bsf PORTC,3 ; SCL=1 | |
60 nop | |
61 nop | |
62 nop | |
63 nop | |
64 btfsc PORTC,4 ; SDA=1? | |
65 bra I2CReset_2 ; =1, SDA has been released from slave | |
66 bcf PORTC,3 ; SCL=0 | |
67 nop | |
68 nop | |
69 bcf PORTC,3 | |
70 nop | |
71 nop | |
72 decfsz i2c_temp,F | |
73 bra I2CReset_1 ; check for nine clock cycles | |
74 I2CReset_2: | |
75 bsf TRISC,3 ; SCL Input | |
76 clrf SSP1CON1 ; setup I²C Mode | |
77 WAITMS d'10' ; Reset-Timeout for I2C devices | |
78 movlw b'00000000' ; with slew rate control | |
79 movwf SSPSTAT | |
80 movlw b'00101000' | |
81 movwf SSP1CON1 | |
82 movlw b'00000000' | |
83 movwf SSP1CON2 | |
84 movlw 0x27 | |
85 movwf SSP1ADD | |
86 return | |
87 | |
88 I2C_TX: | |
89 movwf SSP1BUF | |
90 rcall WaitMSSP | |
91 bra I2C_WaitforACK ; Returns... | |
92 | |
93 I2C_TwoBytesRX_div16: ; Get two bytes and devide lo:hi/16 (signed) | |
94 rcall I2C_OneByteRX ; Get one byte | |
95 movff SSP1BUF,hi ; Data Byte | |
96 rcall I2C_OneByteRX ; Get one byte | |
97 movff SSP1BUF,lo ; Data Byte | |
98 I2C_TwoBytesRX_div16_2: ; devide lo:hi/16 (signed) only | |
99 bcf STATUS,C | |
100 btfsc hi,7 ; Copy sign bit to carry | |
101 bsf STATUS,C | |
102 rrcf hi ; /2 | |
103 rrcf lo | |
104 bcf STATUS,C | |
105 btfsc hi,7 ; Copy sign bit to carry | |
106 bsf STATUS,C | |
107 rrcf hi ; /4 | |
108 rrcf lo | |
109 bcf STATUS,C | |
110 btfsc hi,7 ; Copy sign bit to carry | |
111 bsf STATUS,C | |
112 rrcf hi ; /8 | |
113 rrcf lo | |
114 bcf STATUS,C | |
115 btfsc hi,7 ; Copy sign bit to carry | |
116 bsf STATUS,C | |
117 rrcf hi ; /16 | |
118 rrcf lo | |
119 return | |
120 | |
121 global I2C_RX_accelerometer | |
122 I2C_RX_accelerometer: | |
123 bsf SSP1CON2,SEN ; Start condition | |
124 rcall WaitMSSP | |
125 movlw 0x38 ; address | |
126 rcall I2C_TX | |
158 | 127 movlw 0x00 |
0 | 128 rcall I2C_TX |
129 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
130 rcall WaitMSSP | |
131 movlw 0x39 ; address | |
132 rcall I2C_TX | |
133 | |
158 | 134 rcall I2C_OneByteRX ; Get Status Byte |
135 movf SSP1BUF,W | |
136 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
137 ; Non-flipped screen: |
0 | 138 ; Chip orientation on the PCB requires |
139 ; Original = Corrected | |
140 ; x = -x | |
141 ; y = -y | |
142 ; z = -z | |
143 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
144 ; Flipped screen: |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
145 ; Chip orientation on the PCB requires |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
146 ; Original = Corrected |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
147 ; x = x |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
148 ; y = y |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
149 ; z = -z |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
150 |
0 | 151 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed) |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
152 btfsc flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
153 bra I2C_RX_accelerometer2 ; Yes |
0 | 154 comf hi ; 16bit sign change. |
155 negf lo | |
156 btfsc STATUS,C ; Carry to propagate ? | |
157 incf hi,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
158 I2C_RX_accelerometer2: |
0 | 159 movff lo,accel_DX+0 |
160 movff hi,accel_DX+1 ; Copy result | |
161 | |
162 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed) | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
163 btfsc flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
164 bra I2C_RX_accelerometer3 ; Yes |
0 | 165 comf hi ; 16bit sign change. |
166 negf lo | |
167 btfsc STATUS,C ; Carry to propagate ? | |
168 incf hi,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
169 I2C_RX_accelerometer3: |
0 | 170 movff lo,accel_DY+0 |
171 movff hi,accel_DY+1 ; Copy result | |
172 | |
173 rcall I2C_OneByteRX ; Get one byte | |
174 movff SSP1BUF,hi ; Data Byte | |
175 bsf SSP1CON2, RCEN ; Enable recieve mode | |
176 rcall WaitMSSP | |
177 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+0)... | |
178 movff SSP1BUF,lo ; Data Byte | |
179 | |
180 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
181 comf hi ; 16bit sign change. | |
182 negf lo | |
183 btfsc STATUS,C ; Carry to propagate ? | |
184 incf hi,F ; YES: do it. | |
185 movff lo,accel_DZ+0 | |
186 movff hi,accel_DZ+1 ; Copy result | |
187 | |
188 bsf SSP1CON2,PEN ; Stop condition | |
189 rcall WaitMSSP | |
190 return | |
191 | |
192 I2C_OneByteRX: | |
193 bsf SSP1CON2, RCEN ; Enable recieve mode | |
194 rcall WaitMSSP | |
195 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
196 rcall WaitMSSP | |
197 return | |
198 | |
199 global I2C_RX_compass | |
200 I2C_RX_compass: | |
201 bsf SSP1CON2,SEN ; Start condition | |
202 rcall WaitMSSP | |
203 movlw 0x3C ; address | |
204 rcall I2C_TX | |
205 movlw 0x03 | |
206 rcall I2C_TX | |
207 bsf SSP1CON2,PEN ; Stop condition | |
208 rcall WaitMSSP | |
209 | |
210 bcf PIR1,SSPIF | |
211 bsf SSP1CON2,SEN ; Start condition | |
212 rcall WaitMSSP | |
213 movlw 0x3D ; address | |
214 rcall I2C_TX | |
215 | |
216 ; Compass IC sends data in following order: | |
217 ; x MSB | |
218 ; x LSB | |
219 ; z MSB | |
220 ; z LSB | |
221 ; y MSB | |
222 ; y LSB | |
223 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
224 ; Non-flipped screen |
0 | 225 ; Chip orientation on the PCB requires |
226 ; Original = Corrected | |
227 ; x = -y | |
228 ; z = z | |
229 ; y = x | |
230 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
231 ; Flipped screen |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
232 ; Chip orientation on the PCB requires |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
233 ; Original = Corrected |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
234 ; x = y |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
235 ; z = z |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
236 ; y = -x |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
237 |
0 | 238 rcall I2C_OneByteRX ; Get one byte |
239 movff SSP1BUF,compass_DY+1; Data Byte | |
240 rcall I2C_OneByteRX ; Get one byte | |
241 movff SSP1BUF,compass_DY+0; Data Byte | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
242 btfsc flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
243 bra I2C_RX_compass2 ; Yes |
0 | 244 banksel compass_DY |
245 comf compass_DY+1 ; 16bit sign change. | |
246 negf compass_DY+0 | |
247 btfsc STATUS,C ; Carry to propagate ? | |
248 incf compass_DY+1,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
249 I2C_RX_compass2: |
0 | 250 banksel common |
251 rcall I2C_OneByteRX ; Get one byte | |
252 movff SSP1BUF,compass_DZ+1; Data Byte | |
253 rcall I2C_OneByteRX ; Get one byte | |
254 movff SSP1BUF,compass_DZ+0; Data Byte | |
255 rcall I2C_OneByteRX ; Get one byte | |
256 movff SSP1BUF,compass_DX+1; Data Byte | |
257 bsf SSP1CON2, RCEN ; Enable recieve mode | |
258 rcall WaitMSSP | |
259 movff SSP1BUF,compass_DX+0; Data Byte | |
260 bsf SSP1CON2,PEN ; Stop condition | |
261 rcall WaitMSSP | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
262 btfss flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
263 return ; No, done. |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
264 ; Yes, flip X |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
265 banksel compass_DX |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
266 comf compass_DX+1 ; 16bit sign change. |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
267 negf compass_DX+0 |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
268 btfsc STATUS,C ; Carry to propagate ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
269 incf compass_DX+1,F ; YES: do it. |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
270 banksel common |
0 | 271 return |
272 | |
273 global I2C_init_compass | |
274 I2C_init_compass: | |
275 bsf SSP1CON2,SEN ; Start condition | |
276 rcall WaitMSSP | |
277 movlw 0x3C ; address | |
278 rcall I2C_TX | |
279 movlw 0x00 | |
280 rcall I2C_TX | |
281 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) | |
282 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged | |
283 rcall I2C_TX | |
20 | 284 bra I2C_init_compass_common |
285 | |
286 global I2C_init_compass_fast | |
287 I2C_init_compass_fast: | |
288 bsf SSP1CON2,SEN ; Start condition | |
289 rcall WaitMSSP | |
290 movlw 0x3C ; address | |
291 rcall I2C_TX | |
292 movlw 0x00 | |
293 rcall I2C_TX | |
294 movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged | |
295 ; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) | |
296 rcall I2C_TX | |
297 I2C_init_compass_common: | |
18
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
298 movff opt_compass_gain,i2c_temp ; 0-7 (230LSB/Gauss to 1370LSB/Gaus) |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
299 swapf i2c_temp,F |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
300 comf i2c_temp,F |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
301 bcf STATUS,C |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
302 rlcf i2c_temp |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
303 movf i2c_temp,W |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
304 clrf i2c_temp |
0 | 305 rcall I2C_TX |
306 movlw b'00000000' ; Continous Mode | |
307 rcall I2C_TX | |
308 bsf SSP1CON2,PEN ; Stop condition | |
309 rcall WaitMSSP | |
310 bsf compass_enabled | |
311 return | |
312 | |
313 global I2C_sleep_compass | |
314 I2C_sleep_compass: | |
315 bsf SSP1CON2,SEN ; Start condition | |
316 rcall WaitMSSP | |
317 movlw 0x3C ; address | |
318 rcall I2C_TX | |
319 movlw 0x00 | |
320 rcall I2C_TX | |
321 movlw b'01101000' ; ConfigA | |
322 rcall I2C_TX | |
323 movlw b'00100000' ; ConfigB | |
324 rcall I2C_TX | |
325 movlw b'00000010' ; Idle Mode | |
326 rcall I2C_TX | |
327 bsf SSP1CON2,PEN ; Stop condition | |
328 rcall WaitMSSP | |
329 bcf compass_enabled | |
330 return | |
331 | |
332 | |
333 global I2C_init_accelerometer | |
334 I2C_init_accelerometer: | |
335 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode | |
336 | |
337 bsf SSP1CON2,SEN ; Start condition | |
338 rcall WaitMSSP | |
339 movlw 0x38 ; address | |
340 rcall I2C_TX | |
341 movlw 0x0E ; XYZ_DATA_CFG | |
342 rcall I2C_TX | |
343 movlw b'00000000' ; High pass Filter=0 , +/- 2g range | |
344 rcall I2C_TX | |
345 bsf SSP1CON2,PEN ; Stop condition | |
346 rcall WaitMSSP | |
347 | |
348 | |
349 bsf SSP1CON2,SEN ; Start condition | |
350 rcall WaitMSSP | |
351 movlw 0x38 ; address | |
352 rcall I2C_TX | |
353 movlw 0x2A ; CTRL_REG1 | |
354 rcall I2C_TX | |
355 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode | |
356 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode | |
357 rcall I2C_TX | |
358 movlw b'00000010' ; CTRL_REG2: High Res in Active mode | |
359 rcall I2C_TX | |
360 bsf SSP1CON2,PEN ; Stop condition | |
361 rcall WaitMSSP | |
362 | |
363 bsf SSP1CON2,SEN ; Start condition | |
364 rcall WaitMSSP | |
365 movlw 0x38 ; address | |
366 rcall I2C_TX | |
367 movlw 0x2A ; CTRL_REG1 | |
368 rcall I2C_TX | |
369 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode | |
370 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode | |
371 rcall I2C_TX | |
372 bsf SSP1CON2,PEN ; Stop condition | |
373 rcall WaitMSSP | |
374 | |
375 return | |
376 | |
377 global I2C_sleep_accelerometer | |
378 I2C_sleep_accelerometer: | |
379 bsf SSP1CON2,SEN ; Start condition | |
380 rcall WaitMSSP | |
381 movlw 0x38 ; address | |
382 rcall I2C_TX | |
383 movlw 0x2A ; CTRL_REG1 | |
384 rcall I2C_TX | |
385 movlw b'00000000' ; St. By Mode | |
386 rcall I2C_TX | |
387 bsf SSP1CON2,PEN ; Stop condition | |
388 rcall WaitMSSP | |
389 return | |
390 | |
113 | 391 global lt2942_init |
392 lt2942_init: ; Setup Control register B | |
393 clrf i2c_temp | |
394 movlw 0x01 ; Point to control reg B | |
395 call I2C_TX_GAUGE | |
396 movlw b'11111000' ; Automatic conversion every two seconds | |
397 movff WREG, SSP1BUF ; Data Byte | |
398 rcall WaitMSSP | |
399 rcall I2C_WaitforACK | |
400 bsf SSP1CON2,PEN ; Stop condition | |
401 rcall WaitMSSP | |
402 return | |
403 | |
404 global lt2942_get_status | |
405 lt2942_get_status: ; Read status register | |
235
23311219dacc
under construction: new hardware_flag to configure different hardware versions
heinrichsweikamp
parents:
211
diff
changeset
|
406 bcf rechargeable ; Clear flag |
113 | 407 clrf i2c_temp |
408 movlw 0x00 ; Point to Status reg | |
409 call I2C_TX_GAUGE | |
410 call I2C_RX_GAUGE | |
411 movff SSP1BUF,WREG | |
412 btfss WREG,7 ; 2942 found? | |
235
23311219dacc
under construction: new hardware_flag to configure different hardware versions
heinrichsweikamp
parents:
211
diff
changeset
|
413 bsf rechargeable ; Yes, set flag |
113 | 414 bsf SSP1CON2,PEN ; Stop condition |
415 rcall WaitMSSP | |
416 return | |
417 | |
418 | |
419 global lt2942_get_voltage | |
420 lt2942_get_voltage: ; Read battery voltage registers | |
421 clrf i2c_temp | |
422 movlw 0x08 ; Point to voltage registers | |
423 call I2C_TX_GAUGE | |
424 call I2C_RX_GAUGE | |
425 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
426 rcall WaitMSSP | |
427 movff SSP1BUF,xA+1 | |
428 bsf SSP1CON2, RCEN ; Enable recieve mode | |
429 rcall WaitMSSP | |
430 movff SSP1BUF,xA+0 | |
431 bsf SSP1CON2,PEN ; Stop condition | |
432 rcall WaitMSSP | |
433 | |
434 ; banksel common | |
435 ; xA:2 loaded with raw values | |
436 movlw LOW .6000 | |
437 movwf xB+0 | |
438 movlw HIGH .6000 | |
439 movwf xB+1 | |
440 call mult16x16 ;xA*xB=xC | |
441 | |
442 ; devide xC (32bit)/65535 for result in mV (16bit) | |
443 movlw .16 | |
444 movwf i2c_temp | |
445 lt2942_get_voltage2: | |
446 bcf STATUS,C | |
447 rrcf xC+3,F | |
448 rrcf xC+2,F | |
449 rrcf xC+1,F | |
450 rrcf xC+0,F | |
451 decfsz i2c_temp,F | |
452 bra lt2942_get_voltage2 | |
453 | |
454 ; Update battery voltage in mV | |
455 movff xC+1,batt_voltage+1 | |
456 movff xC+0,batt_voltage+0 | |
457 return | |
458 | |
459 ; global lt2942_get_temperature | |
460 ;lt2942_get_temperature: ; Read temperature registers | |
461 ; clrf i2c_temp | |
462 ; movlw 0x0C ; Point to temperature registers | |
463 ; call I2C_TX_GAUGE | |
464 ; call I2C_RX | |
465 ; bsf SSP1CON2,ACKEN ; Master acknowlegde | |
466 ; rcall WaitMSSP | |
467 ; movff SSP1BUF,xA+1 | |
468 ; bsf SSP1CON2, RCEN ; Enable recieve mode | |
469 ; rcall WaitMSSP | |
470 ; movff SSP1BUF,xA+0 | |
471 ; bsf SSP1CON2,PEN ; Stop condition | |
472 ; rcall WaitMSSP | |
473 ; | |
474 ;; banksel common | |
475 ; ; xA:2 loaded with raw values | |
476 ; movlw LOW .6000 | |
477 ; movwf xB+0 | |
478 ; movlw HIGH .6000 | |
479 ; movwf xB+1 | |
480 ; call mult16x16 ;xA*xB=xC | |
481 ; | |
482 ; ; devide xC (32bit)/65535 for result in 0.1K (16bit) | |
483 ; movlw .16 | |
484 ; movwf i2c_temp | |
485 ;lt2942_get_temperature2: | |
486 ; bcf STATUS,C | |
487 ; rrcf xC+3,F | |
488 ; rrcf xC+2,F | |
489 ; rrcf xC+1,F | |
490 ; rrcf xC+0,F | |
491 ; decfsz i2c_temp,F | |
492 ; bra lt2942_get_temperature2 | |
493 ; | |
494 ; movff xC+1,sub_a+1 | |
495 ; movff xC+0,sub_a+0 | |
496 ; movlw LOW .2731 ; Kelvin to Celcius offset | |
497 ; movwf sub_b+0 | |
498 ; movlw HIGH .2731 ; Kelvin to Celcius offset | |
499 ; movwf sub_b+1 | |
500 ; call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) | |
501 ; | |
502 ; ; Update batttery_temperature in 0.1°C | |
503 ; movff sub_c+1,battery_temperature+1 | |
504 ; movff sub_c+0,battery_temperature+0 | |
505 ; return | |
506 | |
507 global lt2942_get_accumulated_charge | |
508 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent | |
509 clrf i2c_temp | |
510 movlw 0x02 ; Point to accumulated charge registers | |
511 call I2C_TX_GAUGE | |
512 call I2C_RX_GAUGE | |
513 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
514 rcall WaitMSSP | |
515 movff SSP1BUF,sub_a+1 ; battery_acumulated_charge+1 | |
516 bsf SSP1CON2, RCEN ; Enable recieve mode | |
517 rcall WaitMSSP | |
518 movff SSP1BUF,sub_a+0 ; battery_acumulated_charge+0 | |
519 bsf SSP1CON2,PEN ; Stop condition | |
520 rcall WaitMSSP | |
521 | |
522 ; Compute batt_percent | |
211 | 523 ; (charge-battery_offset)/365 |
113 | 524 movlw LOW battery_offset |
525 movwf sub_b+0 | |
526 movlw HIGH battery_offset | |
527 movwf sub_b+1 | |
528 call subU16 ; sub_c = sub_a - sub_b (with signed values) | |
529 | |
530 clrf batt_percent ; Set to zero | |
531 btfsc neg_flag ; result negative? | |
532 return ; Yes, done. | |
533 | |
534 ; > Zero, set batt_percent properly | |
535 movff sub_c+0,xA+0 | |
536 movff sub_c+1,xA+1 | |
537 movlw LOW battery_devider | |
538 movwf xB+0 | |
539 movlw HIGH battery_devider | |
540 movwf xB+1 | |
541 call div16x16 ;xA/xB=xC with xA+0 as remainder, uses divB as temp variable | |
542 movff xC+0,batt_percent | |
543 return | |
544 | |
545 global lt2942_charge_done | |
546 lt2942_charge_done: ; Reset accumulating registers to 0xFFFF | |
547 clrf i2c_temp | |
548 movlw 0x02 ; Point to accumulated charge registers | |
549 call I2C_TX_GAUGE | |
550 movlw 0xFF | |
551 movff WREG, SSP1BUF ; Data Byte | |
552 rcall WaitMSSP | |
553 rcall I2C_WaitforACK | |
554 movlw 0xFF | |
555 movff WREG, SSP1BUF ; Data Byte | |
556 rcall WaitMSSP | |
557 rcall I2C_WaitforACK | |
558 bsf SSP1CON2,PEN ; Stop condition | |
559 rcall WaitMSSP | |
560 return | |
561 | |
562 I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC | |
563 movwf i2c_temp+1 ; Data byte | |
564 bsf SSP1CON2,SEN ; Start condition | |
565 rcall WaitMSSP | |
566 movlw b'11001000' ; Address byte + Write bit | |
567 movwf SSP1BUF ; control byte | |
568 rcall WaitMSSP | |
569 rcall I2C_WaitforACK | |
570 movff i2c_temp+1, SSP1BUF ; Data Byte | |
571 rcall WaitMSSP | |
572 rcall I2C_WaitforACK | |
573 return | |
574 | |
575 I2C_RX_GAUGE: | |
576 bsf SSP1CON2,SEN ; Start condition | |
577 rcall WaitMSSP | |
578 movlw b'11001001' ; Address byte + Read bit | |
579 movwf SSP1BUF ; control byte | |
580 rcall WaitMSSP | |
581 rcall I2C_WaitforACK | |
582 bsf SSP1CON2, RCEN ; Enable recieve mode | |
583 rcall WaitMSSP | |
584 return | |
585 | |
586 | |
0 | 587 |
588 END |