Mercurial > public > hwos_code
annotate src/i2c.asm @ 431:9500b2d3e32b
hunting a bug in the logbook...
author | heinrichsweikamp |
---|---|
date | Tue, 21 Jun 2016 17:20:44 +0200 |
parents | 4b93354b7738 |
children | aadfe9f2edaf |
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 ; | |
427 | 13 ; LSM303D's read address (8-Bit): 0x3D |
14 ; LSM303D's write address (8-Bit): 0x3C | |
15 ; | |
0 | 16 ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. |
17 ;============================================================================= | |
18 ; HISTORY | |
19 ; 2012-08-22 : [mH] Creation | |
20 | |
21 | |
275 | 22 #include "hwos.inc" ; Mandatory header |
0 | 23 #include "wait.inc" |
113 | 24 #include "math.inc" |
25 | |
200 | 26 #DEFINE battery_offset .29065 ; 65536-(3,1Ah/0,085mAh) |
27 #DEFINE battery_devider .365 ; 3,1Ah/0,085mAh/100 [%] | |
0 | 28 |
29 i2c CODE | |
30 | |
31 WaitMSSP: | |
32 decfsz i2c_temp,F ; check for timeout during I2C action | |
33 bra WaitMSSP2 | |
34 bra I2CFail ; timeout occured | |
35 WaitMSSP2: | |
36 btfss PIR1,SSPIF | |
37 bra WaitMSSP | |
38 clrf i2c_temp | |
39 bcf PIR1,SSPIF | |
40 nop | |
41 return | |
42 | |
43 I2C_WaitforACK: | |
44 btfss SSPCON2,ACKSTAT ; checks for ACK bit from slave | |
45 return | |
46 I2CFail: | |
47 rcall I2CReset ; I2C Reset | |
48 bcf PIR1,SSPIF | |
49 clrf i2c_temp | |
50 return | |
51 | |
52 I2CReset: ; Something went wrong (Slave holds SDA low?) | |
53 clrf SSP1CON1 ; wake-up slave and reset entire module | |
54 clrf SSP1CON2 | |
55 clrf SSP1STAT | |
56 bcf TRISC,3 ; SCL OUTPUT | |
57 bsf TRISC,4 ; SDA Input | |
58 bcf PORTC,3 | |
59 movlw d'9' | |
60 movwf i2c_temp ; clock-out 9 clock cycles manually | |
61 I2CReset_1: | |
62 bsf PORTC,3 ; SCL=1 | |
63 nop | |
64 nop | |
65 nop | |
66 nop | |
67 btfsc PORTC,4 ; SDA=1? | |
68 bra I2CReset_2 ; =1, SDA has been released from slave | |
69 bcf PORTC,3 ; SCL=0 | |
70 nop | |
71 nop | |
72 bcf PORTC,3 | |
73 nop | |
74 nop | |
75 decfsz i2c_temp,F | |
76 bra I2CReset_1 ; check for nine clock cycles | |
77 I2CReset_2: | |
78 bsf TRISC,3 ; SCL Input | |
79 clrf SSP1CON1 ; setup I²C Mode | |
80 WAITMS d'10' ; Reset-Timeout for I2C devices | |
81 movlw b'00000000' ; with slew rate control | |
82 movwf SSPSTAT | |
83 movlw b'00101000' | |
84 movwf SSP1CON1 | |
85 movlw b'00000000' | |
86 movwf SSP1CON2 | |
87 movlw 0x27 | |
88 movwf SSP1ADD | |
89 return | |
90 | |
91 I2C_TX: | |
92 movwf SSP1BUF | |
93 rcall WaitMSSP | |
94 bra I2C_WaitforACK ; Returns... | |
95 | |
96 I2C_TwoBytesRX_div16: ; Get two bytes and devide lo:hi/16 (signed) | |
97 rcall I2C_OneByteRX ; Get one byte | |
98 movff SSP1BUF,hi ; Data Byte | |
99 rcall I2C_OneByteRX ; Get one byte | |
100 movff SSP1BUF,lo ; Data Byte | |
101 I2C_TwoBytesRX_div16_2: ; devide lo:hi/16 (signed) only | |
102 bcf STATUS,C | |
103 btfsc hi,7 ; Copy sign bit to carry | |
104 bsf STATUS,C | |
105 rrcf hi ; /2 | |
427 | 106 rrcf lo |
107 I2C_TwoBytesRX_div8_2: ; devide lo:hi/8 (signed) only | |
0 | 108 bcf STATUS,C |
109 btfsc hi,7 ; Copy sign bit to carry | |
110 bsf STATUS,C | |
111 rrcf hi ; /4 | |
427 | 112 rrcf lo |
0 | 113 bcf STATUS,C |
114 btfsc hi,7 ; Copy sign bit to carry | |
115 bsf STATUS,C | |
116 rrcf hi ; /8 | |
117 rrcf lo | |
118 bcf STATUS,C | |
119 btfsc hi,7 ; Copy sign bit to carry | |
120 bsf STATUS,C | |
121 rrcf hi ; /16 | |
122 rrcf lo | |
123 return | |
124 | |
125 global I2C_RX_accelerometer | |
126 I2C_RX_accelerometer: | |
427 | 127 btfsc compass_type ; compass1? |
128 bra I2C_RX_accelerometer_compass1 ; yes | |
129 ;I2C_RX_accelerometer_compass0: | |
130 bsf SSP1CON2,SEN ; Start condition | |
131 rcall WaitMSSP | |
132 movlw 0x38 ; address | |
0 | 133 rcall I2C_TX |
427 | 134 movlw 0x00 |
0 | 135 rcall I2C_TX |
427 | 136 bsf SSP1CON2,RSEN ; Repeated start condition (!) |
137 rcall WaitMSSP | |
138 movlw 0x39 ; address | |
0 | 139 rcall I2C_TX |
140 | |
158 | 141 rcall I2C_OneByteRX ; Get Status Byte |
142 movf SSP1BUF,W | |
143 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
144 ; Non-flipped screen: |
0 | 145 ; Chip orientation on the PCB requires |
146 ; Original = Corrected | |
147 ; x = -x | |
148 ; y = -y | |
149 ; z = -z | |
150 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
151 ; Flipped screen: |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
152 ; Chip orientation on the PCB requires |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
153 ; Original = Corrected |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
154 ; x = x |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
155 ; y = y |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
156 ; z = -z |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
157 |
0 | 158 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
|
159 btfsc flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
160 bra I2C_RX_accelerometer2 ; Yes |
0 | 161 comf hi ; 16bit sign change. |
162 negf lo | |
163 btfsc STATUS,C ; Carry to propagate ? | |
164 incf hi,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
165 I2C_RX_accelerometer2: |
0 | 166 movff lo,accel_DX+0 |
167 movff hi,accel_DX+1 ; Copy result | |
168 | |
169 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
|
170 btfsc flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
171 bra I2C_RX_accelerometer3 ; Yes |
0 | 172 comf hi ; 16bit sign change. |
173 negf lo | |
174 btfsc STATUS,C ; Carry to propagate ? | |
175 incf hi,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
176 I2C_RX_accelerometer3: |
0 | 177 movff lo,accel_DY+0 |
178 movff hi,accel_DY+1 ; Copy result | |
179 | |
180 rcall I2C_OneByteRX ; Get one byte | |
181 movff SSP1BUF,hi ; Data Byte | |
182 bsf SSP1CON2, RCEN ; Enable recieve mode | |
183 rcall WaitMSSP | |
184 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+0)... | |
185 movff SSP1BUF,lo ; Data Byte | |
186 | |
187 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
188 comf hi ; 16bit sign change. | |
189 negf lo | |
190 btfsc STATUS,C ; Carry to propagate ? | |
191 incf hi,F ; YES: do it. | |
192 movff lo,accel_DZ+0 | |
193 movff hi,accel_DZ+1 ; Copy result | |
194 | |
195 bsf SSP1CON2,PEN ; Stop condition | |
196 rcall WaitMSSP | |
197 return | |
198 | |
427 | 199 I2C_RX_accelerometer_compass1: |
200 bsf SSP1CON2,SEN ; Start condition | |
201 rcall WaitMSSP | |
202 movlw 0x3C ; address | |
203 rcall I2C_TX | |
204 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) | |
205 rcall I2C_TX | |
206 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
207 rcall WaitMSSP | |
208 movlw 0x3D ; address | |
209 rcall I2C_TX | |
210 | |
211 ; Non-flipped screen: | |
212 ; Chip orientation on the PCB requires | |
213 ; Original = Corrected | |
214 ; x = -x | |
215 ; y = -y | |
216 ; z = -z | |
217 | |
218 ; Flipped screen: | |
219 ; Chip orientation on the PCB requires | |
220 ; Original = Corrected | |
221 ; x = x | |
222 ; y = y | |
223 ; z = -z | |
224 | |
225 ; Dump the accelerator data | |
226 rcall I2C_OneByteRX | |
227 movff SSP1BUF,lo ;accel_DX+0 | |
228 rcall I2C_OneByteRX | |
229 movff SSP1BUF,hi ;accel_DX+1 | |
230 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
231 btfsc flip_screen ; 180° rotation ? | |
232 bra I2C_RX_accelerometer2_c1 ; Yes | |
233 comf hi ; 16bit sign change. | |
234 negf lo | |
235 btfsc STATUS,C ; Carry to propagate ? | |
236 incf hi,F ; YES: do it. | |
237 I2C_RX_accelerometer2_c1: | |
238 movff lo,accel_DX+0 | |
239 movff hi,accel_DX+1 ; Copy result | |
240 | |
241 rcall I2C_OneByteRX | |
242 movff SSP1BUF,lo ;accel_DY+0 | |
243 rcall I2C_OneByteRX | |
244 movff SSP1BUF,hi ;accel_DY+1 | |
245 | |
246 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
247 btfsc flip_screen ; 180° rotation ? | |
248 bra I2C_RX_accelerometer3_c1 ; Yes | |
249 comf hi ; 16bit sign change. | |
250 negf lo | |
251 btfsc STATUS,C ; Carry to propagate ? | |
252 incf hi,F ; YES: do it. | |
253 I2C_RX_accelerometer3_c1: | |
254 movff lo,accel_DY+0 | |
255 movff hi,accel_DY+1 ; Copy result | |
256 | |
257 rcall I2C_OneByteRX | |
258 movff SSP1BUF,lo ;accel_DZ+0 | |
259 bsf SSP1CON2, RCEN ; Enable recieve mode | |
260 rcall WaitMSSP | |
261 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+1)... | |
262 movff SSP1BUF,hi ;accel_DZ+1 | |
263 bsf SSP1CON2,PEN ; Stop condition | |
264 rcall WaitMSSP | |
265 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
266 comf hi ; 16bit sign change for Z | |
267 negf lo | |
268 btfsc STATUS,C ; Carry to propagate ? | |
269 incf hi,F ; YES: do it. | |
270 movff lo,accel_DZ+0 | |
271 movff hi,accel_DZ+1 ; Copy result | |
272 return | |
273 | |
0 | 274 I2C_OneByteRX: |
427 | 275 bsf SSP1CON2, RCEN ; Enable recieve mode |
276 rcall WaitMSSP | |
277 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
278 bra WaitMSSP ; And return! | |
0 | 279 |
280 global I2C_RX_compass | |
281 I2C_RX_compass: | |
427 | 282 btfsc compass_type ; compass1? |
283 bra I2C_RX_compass1 ; yes | |
284 ;I2C_RX_compass0: | |
285 bsf SSP1CON2,SEN ; Start condition | |
286 rcall WaitMSSP | |
287 movlw 0x3C ; address | |
0 | 288 rcall I2C_TX |
427 | 289 movlw 0x03 |
290 rcall I2C_TX | |
291 bsf SSP1CON2,PEN ; Stop condition | |
292 rcall WaitMSSP | |
0 | 293 |
427 | 294 bcf PIR1,SSPIF |
295 bsf SSP1CON2,SEN ; Start condition | |
296 rcall WaitMSSP | |
297 movlw 0x3D ; address | |
0 | 298 rcall I2C_TX |
299 | |
300 ; Compass IC sends data in following order: | |
301 ; x MSB | |
302 ; x LSB | |
303 ; z MSB | |
304 ; z LSB | |
305 ; y MSB | |
306 ; y LSB | |
307 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
308 ; Non-flipped screen |
0 | 309 ; Chip orientation on the PCB requires |
310 ; Original = Corrected | |
311 ; x = -y | |
312 ; z = z | |
313 ; y = x | |
314 | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
315 ; Flipped screen |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
316 ; Chip orientation on the PCB requires |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
317 ; Original = Corrected |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
318 ; x = y |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
319 ; z = z |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
320 ; y = -x |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
321 |
0 | 322 rcall I2C_OneByteRX ; Get one byte |
323 movff SSP1BUF,compass_DY+1; Data Byte | |
324 rcall I2C_OneByteRX ; Get one byte | |
325 movff SSP1BUF,compass_DY+0; Data Byte | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
326 btfsc flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
327 bra I2C_RX_compass2 ; Yes |
0 | 328 banksel compass_DY |
329 comf compass_DY+1 ; 16bit sign change. | |
330 negf compass_DY+0 | |
331 btfsc STATUS,C ; Carry to propagate ? | |
332 incf compass_DY+1,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
333 I2C_RX_compass2: |
0 | 334 banksel common |
335 rcall I2C_OneByteRX ; Get one byte | |
427 | 336 movff SSP1BUF,compass_DZ+1; Data Byte |
0 | 337 rcall I2C_OneByteRX ; Get one byte |
427 | 338 movff SSP1BUF,compass_DZ+0; Data Byte |
0 | 339 rcall I2C_OneByteRX ; Get one byte |
427 | 340 movff SSP1BUF,compass_DX+1; Data Byte |
341 bsf SSP1CON2, RCEN ; Enable recieve mode | |
342 rcall WaitMSSP | |
343 movff SSP1BUF,compass_DX+0; Data Byte | |
344 bsf SSP1CON2,PEN ; Stop condition | |
345 rcall WaitMSSP | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
346 btfss flip_screen ; 180° rotation ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
347 return ; No, done. |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
348 ; Yes, flip X |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
349 banksel compass_DX |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
350 comf compass_DX+1 ; 16bit sign change. |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
351 negf compass_DX+0 |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
352 btfsc STATUS,C ; Carry to propagate ? |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
353 incf compass_DX+1,F ; YES: do it. |
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
354 banksel common |
0 | 355 return |
427 | 356 |
357 I2C_RX_compass1: ; New compass | |
358 bsf SSP1CON2,SEN ; Start condition | |
359 rcall WaitMSSP | |
360 movlw 0x3C ; address | |
361 rcall I2C_TX | |
362 movlw b'10001000' ; 0x08 with auto-increment (MSB=1) | |
363 rcall I2C_TX | |
364 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
365 rcall WaitMSSP | |
366 movlw 0x3D ; address | |
367 rcall I2C_TX | |
368 | |
369 rcall I2C_OneByteRX ; Get one byte | |
370 movff SSP1BUF,lo ; Data Byte | |
371 rcall I2C_OneByteRX ; Get one byte | |
372 movff SSP1BUF,hi ; Data Byte | |
373 rcall I2C_TwoBytesRX_div8_2 | |
374 movff lo,compass_DX+0 | |
375 movff hi,compass_DX+1 | |
376 btfss flip_screen ; 180° rotation ? | |
377 bra I2C_RX_compass1_1 ; Yes | |
378 ; Yes, flip X | |
379 banksel compass_DX | |
380 comf compass_DX+1 ; 16bit sign change. | |
381 negf compass_DX+0 | |
382 btfsc STATUS,C ; Carry to propagate ? | |
383 incf compass_DX+1,F ; YES: do it. | |
384 banksel common | |
385 I2C_RX_compass1_1: | |
386 rcall I2C_OneByteRX ; Get one byte | |
387 movff SSP1BUF,lo ; Data Byte | |
388 rcall I2C_OneByteRX ; Get one byte | |
389 movff SSP1BUF,hi ; Data Byte | |
390 rcall I2C_TwoBytesRX_div8_2 | |
391 movff lo,compass_DY+0 | |
392 movff hi,compass_DY+1 | |
393 btfss flip_screen ; 180° rotation ? | |
394 bra I2C_RX_compass1_2 ; Yes | |
395 ; Yes, flip Y | |
396 banksel compass_DY | |
397 comf compass_DY+1 ; 16bit sign change. | |
398 negf compass_DY+0 | |
399 btfsc STATUS,C ; Carry to propagate ? | |
400 incf compass_DY+1,F ; YES: do it. | |
401 I2C_RX_compass1_2: | |
402 banksel common | |
403 rcall I2C_OneByteRX ; Get one byte | |
404 movff SSP1BUF,lo ; Data Byte | |
405 bsf SSP1CON2, RCEN ; Enable recieve mode | |
406 rcall WaitMSSP | |
407 movff SSP1BUF,hi ; Data Byte | |
408 rcall I2C_TwoBytesRX_div8_2 | |
409 movff lo,compass_DZ+0 | |
410 movff hi,compass_DZ+1 | |
411 bsf SSP1CON2,PEN ; Stop condition | |
412 rcall WaitMSSP | |
413 return | |
0 | 414 |
415 global I2C_init_compass | |
416 I2C_init_compass: | |
427 | 417 bsf compass_enabled |
418 bsf compass_type ; set flag | |
419 bsf SSP1CON2,SEN ; Start condition | |
420 rcall WaitMSSP | |
421 movlw 0x3C ; address | |
422 rcall I2C_TX | |
423 movlw 0x0F | |
424 rcall I2C_TX | |
425 bsf SSP1CON2,PEN ; Stop condition | |
426 rcall WaitMSSP | |
427 bcf PIR1,SSPIF | |
428 bsf SSP1CON2,SEN ; Start condition | |
429 rcall WaitMSSP | |
430 movlw 0x3D ; address | |
431 rcall I2C_TX | |
432 rcall I2C_OneByteRX ; Get one byte | |
433 movlw 0x49 ; 0x49 = Compass1 | |
434 cpfseq SSP1BUF | |
435 bcf compass_type ; clear flag | |
436 bsf SSP1CON2,PEN ; Stop condition | |
437 rcall WaitMSSP | |
438 | |
439 btfsc compass_type ; compass1? | |
440 bra I2C_init_compass1 ; yes | |
441 ; init compass0 | |
442 bsf SSP1CON2,SEN ; Start condition | |
443 rcall WaitMSSP | |
444 movlw 0x3C ; address | |
0 | 445 rcall I2C_TX |
427 | 446 movlw 0x00 |
0 | 447 rcall I2C_TX |
427 | 448 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) |
449 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged | |
0 | 450 rcall I2C_TX |
20 | 451 bra I2C_init_compass_common |
452 | |
453 global I2C_init_compass_fast | |
454 I2C_init_compass_fast: | |
427 | 455 btfsc compass_type ; compass1? |
456 bra I2C_init_compass_fast1 ; yes | |
457 ;I2C_init_compass_fast0: | |
458 bsf SSP1CON2,SEN ; Start condition | |
459 rcall WaitMSSP | |
460 movlw 0x3C ; address | |
20 | 461 rcall I2C_TX |
427 | 462 movlw 0x00 |
20 | 463 rcall I2C_TX |
427 | 464 movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged |
465 ; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) | |
20 | 466 rcall I2C_TX |
467 I2C_init_compass_common: | |
427 | 468 movff opt_compass_gain,i2c_temp ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) |
18
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
469 swapf i2c_temp,F |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
470 comf i2c_temp,F |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
471 bcf STATUS,C |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
472 rlcf i2c_temp |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
473 movf i2c_temp,W |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
474 clrf i2c_temp |
0 | 475 rcall I2C_TX |
427 | 476 movlw b'00000000' ; Continous Mode |
0 | 477 rcall I2C_TX |
427 | 478 bsf SSP1CON2,PEN ; Stop condition |
479 rcall WaitMSSP | |
0 | 480 return |
481 | |
427 | 482 I2C_init_compass1: |
483 bsf SSP1CON2,SEN ; Start condition | |
484 rcall WaitMSSP | |
485 movlw 0x3C ; address | |
486 rcall I2C_TX | |
487 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
488 rcall I2C_TX | |
489 movlw b'00000000' ; CTRL0 | |
490 rcall I2C_TX | |
491 movlw b'00101111' ; CTRL1 (6,25Hz, BDU=0, x,y,z = ON) | |
492 rcall I2C_TX | |
493 movlw b'11000000' ; CTRL2 (50Hz, +/-2g, | |
494 rcall I2C_TX | |
495 movlw b'00000000' ; CTRL3 | |
496 rcall I2C_TX | |
497 movlw b'00000000' ; CTRL4 | |
498 rcall I2C_TX | |
499 movlw b'01100100' ; CTRL5 HIGH res, 6,25Hz | |
500 rcall I2C_TX | |
429 | 501 init_compass1_common: |
427 | 502 ;movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) |
503 movlw b'00000000' ; CTRL6 (+/-2 Gauss) | |
504 rcall I2C_TX | |
505 movlw b'00000000' ; CTRL7 Continuous Mode | |
506 rcall I2C_TX | |
507 bsf SSP1CON2,PEN ; Stop condition | |
508 rcall WaitMSSP | |
509 return | |
510 | |
511 I2C_init_compass_fast1: | |
512 bsf SSP1CON2,SEN ; Start condition | |
513 rcall WaitMSSP | |
514 movlw 0x3C ; address | |
515 rcall I2C_TX | |
516 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
517 rcall I2C_TX | |
518 movlw b'00000000' ; CTRL0 | |
519 rcall I2C_TX | |
520 movlw b'01101111' ; CTRL1 (100Hz, BDU=0, x,y,z = ON) | |
521 rcall I2C_TX | |
522 movlw b'11000000' ; CTRL2 (50Hz, +/-2g, | |
523 rcall I2C_TX | |
524 movlw b'00000000' ; CTRL3 | |
525 rcall I2C_TX | |
526 movlw b'00000000' ; CTRL4 | |
527 rcall I2C_TX | |
528 movlw b'01110100' ; CTRL5 HIGH res, 100Hz | |
529 rcall I2C_TX | |
429 | 530 bra init_compass1_common |
427 | 531 |
0 | 532 global I2C_sleep_compass |
533 I2C_sleep_compass: | |
427 | 534 bcf compass_enabled |
535 | |
536 btfsc compass_type ; compass1? | |
537 bra I2C_sleep_compass1 ; yes | |
538 ;I2C_sleep_compass0: | |
539 bsf SSP1CON2,SEN ; Start condition | |
540 rcall WaitMSSP | |
541 movlw 0x3C ; address | |
0 | 542 rcall I2C_TX |
427 | 543 movlw 0x00 |
0 | 544 rcall I2C_TX |
427 | 545 movlw b'01101000' ; ConfigA |
0 | 546 rcall I2C_TX |
427 | 547 movlw b'00100000' ; ConfigB |
548 rcall I2C_TX | |
549 movlw b'00000010' ; Idle Mode | |
550 rcall I2C_TX | |
551 bsf SSP1CON2,PEN ; Stop condition | |
552 rcall WaitMSSP | |
0 | 553 return |
554 | |
427 | 555 I2C_sleep_compass1: |
556 bsf SSP1CON2,SEN ; Start condition | |
557 rcall WaitMSSP | |
558 movlw 0x3C ; address | |
559 rcall I2C_TX | |
560 movlw 0x20 ; CTRL_REG1 | |
561 rcall I2C_TX | |
562 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor Power-down mode | |
563 rcall I2C_TX | |
564 bsf SSP1CON2,PEN ; Stop condition | |
565 rcall WaitMSSP | |
566 bsf SSP1CON2,SEN ; Start condition | |
567 rcall WaitMSSP | |
568 movlw 0x3C ; address | |
569 rcall I2C_TX | |
570 movlw 0x26 ; CTRL_REG7 | |
571 rcall I2C_TX | |
572 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor Power-down mode | |
573 rcall I2C_TX | |
574 bsf SSP1CON2,PEN ; Stop condition | |
575 rcall WaitMSSP | |
576 return | |
577 | |
0 | 578 |
579 global I2C_init_accelerometer | |
580 I2C_init_accelerometer: | |
427 | 581 btfsc compass_type ; compass1? |
582 return ; yes, ignore | |
583 | |
0 | 584 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode |
585 | |
586 bsf SSP1CON2,SEN ; Start condition | |
587 rcall WaitMSSP | |
588 movlw 0x38 ; address | |
589 rcall I2C_TX | |
590 movlw 0x0E ; XYZ_DATA_CFG | |
591 rcall I2C_TX | |
592 movlw b'00000000' ; High pass Filter=0 , +/- 2g range | |
593 rcall I2C_TX | |
594 bsf SSP1CON2,PEN ; Stop condition | |
595 rcall WaitMSSP | |
596 | |
597 | |
598 bsf SSP1CON2,SEN ; Start condition | |
599 rcall WaitMSSP | |
600 movlw 0x38 ; address | |
601 rcall I2C_TX | |
602 movlw 0x2A ; CTRL_REG1 | |
603 rcall I2C_TX | |
604 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode | |
605 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode | |
606 rcall I2C_TX | |
607 movlw b'00000010' ; CTRL_REG2: High Res in Active mode | |
608 rcall I2C_TX | |
609 bsf SSP1CON2,PEN ; Stop condition | |
610 rcall WaitMSSP | |
611 | |
612 bsf SSP1CON2,SEN ; Start condition | |
613 rcall WaitMSSP | |
614 movlw 0x38 ; address | |
615 rcall I2C_TX | |
616 movlw 0x2A ; CTRL_REG1 | |
617 rcall I2C_TX | |
618 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode | |
619 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode | |
620 rcall I2C_TX | |
621 bsf SSP1CON2,PEN ; Stop condition | |
622 rcall WaitMSSP | |
623 | |
624 return | |
625 | |
626 global I2C_sleep_accelerometer | |
627 I2C_sleep_accelerometer: | |
427 | 628 btfsc compass_type ; compass1? |
629 return ; yes, ignore | |
630 | |
0 | 631 bsf SSP1CON2,SEN ; Start condition |
632 rcall WaitMSSP | |
633 movlw 0x38 ; address | |
634 rcall I2C_TX | |
635 movlw 0x2A ; CTRL_REG1 | |
636 rcall I2C_TX | |
637 movlw b'00000000' ; St. By Mode | |
638 rcall I2C_TX | |
639 bsf SSP1CON2,PEN ; Stop condition | |
640 rcall WaitMSSP | |
641 return | |
642 | |
113 | 643 global lt2942_init |
644 lt2942_init: ; Setup Control register B | |
645 clrf i2c_temp | |
646 movlw 0x01 ; Point to control reg B | |
647 call I2C_TX_GAUGE | |
648 movlw b'11111000' ; Automatic conversion every two seconds | |
649 movff WREG, SSP1BUF ; Data Byte | |
650 rcall WaitMSSP | |
651 rcall I2C_WaitforACK | |
652 bsf SSP1CON2,PEN ; Stop condition | |
653 rcall WaitMSSP | |
654 return | |
655 | |
656 global lt2942_get_status | |
657 lt2942_get_status: ; Read status register | |
235
23311219dacc
under construction: new hardware_flag to configure different hardware versions
heinrichsweikamp
parents:
211
diff
changeset
|
658 bcf rechargeable ; Clear flag |
113 | 659 clrf i2c_temp |
660 movlw 0x00 ; Point to Status reg | |
661 call I2C_TX_GAUGE | |
662 call I2C_RX_GAUGE | |
663 movff SSP1BUF,WREG | |
664 btfss WREG,7 ; 2942 found? | |
235
23311219dacc
under construction: new hardware_flag to configure different hardware versions
heinrichsweikamp
parents:
211
diff
changeset
|
665 bsf rechargeable ; Yes, set flag |
113 | 666 bsf SSP1CON2,PEN ; Stop condition |
667 rcall WaitMSSP | |
668 return | |
669 | |
670 | |
671 global lt2942_get_voltage | |
672 lt2942_get_voltage: ; Read battery voltage registers | |
673 clrf i2c_temp | |
674 movlw 0x08 ; Point to voltage registers | |
675 call I2C_TX_GAUGE | |
676 call I2C_RX_GAUGE | |
677 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
678 rcall WaitMSSP | |
679 movff SSP1BUF,xA+1 | |
680 bsf SSP1CON2, RCEN ; Enable recieve mode | |
681 rcall WaitMSSP | |
682 movff SSP1BUF,xA+0 | |
683 bsf SSP1CON2,PEN ; Stop condition | |
684 rcall WaitMSSP | |
685 | |
686 ; banksel common | |
687 ; xA:2 loaded with raw values | |
688 movlw LOW .6000 | |
689 movwf xB+0 | |
690 movlw HIGH .6000 | |
691 movwf xB+1 | |
692 call mult16x16 ;xA*xB=xC | |
693 | |
694 ; devide xC (32bit)/65535 for result in mV (16bit) | |
695 movlw .16 | |
696 movwf i2c_temp | |
697 lt2942_get_voltage2: | |
698 bcf STATUS,C | |
699 rrcf xC+3,F | |
700 rrcf xC+2,F | |
701 rrcf xC+1,F | |
702 rrcf xC+0,F | |
703 decfsz i2c_temp,F | |
704 bra lt2942_get_voltage2 | |
705 | |
706 ; Update battery voltage in mV | |
707 movff xC+1,batt_voltage+1 | |
708 movff xC+0,batt_voltage+0 | |
709 return | |
710 | |
711 ; global lt2942_get_temperature | |
712 ;lt2942_get_temperature: ; Read temperature registers | |
713 ; clrf i2c_temp | |
714 ; movlw 0x0C ; Point to temperature registers | |
715 ; call I2C_TX_GAUGE | |
716 ; call I2C_RX | |
717 ; bsf SSP1CON2,ACKEN ; Master acknowlegde | |
718 ; rcall WaitMSSP | |
719 ; movff SSP1BUF,xA+1 | |
720 ; bsf SSP1CON2, RCEN ; Enable recieve mode | |
721 ; rcall WaitMSSP | |
722 ; movff SSP1BUF,xA+0 | |
723 ; bsf SSP1CON2,PEN ; Stop condition | |
724 ; rcall WaitMSSP | |
725 ; | |
726 ;; banksel common | |
727 ; ; xA:2 loaded with raw values | |
728 ; movlw LOW .6000 | |
729 ; movwf xB+0 | |
730 ; movlw HIGH .6000 | |
731 ; movwf xB+1 | |
732 ; call mult16x16 ;xA*xB=xC | |
733 ; | |
734 ; ; devide xC (32bit)/65535 for result in 0.1K (16bit) | |
735 ; movlw .16 | |
736 ; movwf i2c_temp | |
737 ;lt2942_get_temperature2: | |
738 ; bcf STATUS,C | |
739 ; rrcf xC+3,F | |
740 ; rrcf xC+2,F | |
741 ; rrcf xC+1,F | |
742 ; rrcf xC+0,F | |
743 ; decfsz i2c_temp,F | |
744 ; bra lt2942_get_temperature2 | |
745 ; | |
746 ; movff xC+1,sub_a+1 | |
747 ; movff xC+0,sub_a+0 | |
748 ; movlw LOW .2731 ; Kelvin to Celcius offset | |
749 ; movwf sub_b+0 | |
750 ; movlw HIGH .2731 ; Kelvin to Celcius offset | |
751 ; movwf sub_b+1 | |
752 ; call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) | |
753 ; | |
754 ; ; Update batttery_temperature in 0.1°C | |
755 ; movff sub_c+1,battery_temperature+1 | |
756 ; movff sub_c+0,battery_temperature+0 | |
757 ; return | |
758 | |
759 global lt2942_get_accumulated_charge | |
760 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent | |
761 clrf i2c_temp | |
762 movlw 0x02 ; Point to accumulated charge registers | |
763 call I2C_TX_GAUGE | |
764 call I2C_RX_GAUGE | |
765 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
766 rcall WaitMSSP | |
767 movff SSP1BUF,sub_a+1 ; battery_acumulated_charge+1 | |
768 bsf SSP1CON2, RCEN ; Enable recieve mode | |
769 rcall WaitMSSP | |
770 movff SSP1BUF,sub_a+0 ; battery_acumulated_charge+0 | |
771 bsf SSP1CON2,PEN ; Stop condition | |
772 rcall WaitMSSP | |
773 | |
774 ; Compute batt_percent | |
211 | 775 ; (charge-battery_offset)/365 |
113 | 776 movlw LOW battery_offset |
777 movwf sub_b+0 | |
778 movlw HIGH battery_offset | |
779 movwf sub_b+1 | |
780 call subU16 ; sub_c = sub_a - sub_b (with signed values) | |
781 | |
782 clrf batt_percent ; Set to zero | |
783 btfsc neg_flag ; result negative? | |
784 return ; Yes, done. | |
785 | |
786 ; > Zero, set batt_percent properly | |
787 movff sub_c+0,xA+0 | |
788 movff sub_c+1,xA+1 | |
789 movlw LOW battery_devider | |
790 movwf xB+0 | |
791 movlw HIGH battery_devider | |
792 movwf xB+1 | |
793 call div16x16 ;xA/xB=xC with xA+0 as remainder, uses divB as temp variable | |
794 movff xC+0,batt_percent | |
795 return | |
796 | |
797 global lt2942_charge_done | |
798 lt2942_charge_done: ; Reset accumulating registers to 0xFFFF | |
799 clrf i2c_temp | |
800 movlw 0x02 ; Point to accumulated charge registers | |
801 call I2C_TX_GAUGE | |
802 movlw 0xFF | |
803 movff WREG, SSP1BUF ; Data Byte | |
804 rcall WaitMSSP | |
805 rcall I2C_WaitforACK | |
806 movlw 0xFF | |
807 movff WREG, SSP1BUF ; Data Byte | |
808 rcall WaitMSSP | |
809 rcall I2C_WaitforACK | |
810 bsf SSP1CON2,PEN ; Stop condition | |
811 rcall WaitMSSP | |
812 return | |
813 | |
814 I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC | |
815 movwf i2c_temp+1 ; Data byte | |
816 bsf SSP1CON2,SEN ; Start condition | |
817 rcall WaitMSSP | |
818 movlw b'11001000' ; Address byte + Write bit | |
819 movwf SSP1BUF ; control byte | |
820 rcall WaitMSSP | |
821 rcall I2C_WaitforACK | |
822 movff i2c_temp+1, SSP1BUF ; Data Byte | |
823 rcall WaitMSSP | |
824 rcall I2C_WaitforACK | |
825 return | |
826 | |
827 I2C_RX_GAUGE: | |
828 bsf SSP1CON2,SEN ; Start condition | |
829 rcall WaitMSSP | |
830 movlw b'11001001' ; Address byte + Read bit | |
831 movwf SSP1BUF ; control byte | |
832 rcall WaitMSSP | |
833 rcall I2C_WaitforACK | |
834 bsf SSP1CON2, RCEN ; Enable recieve mode | |
835 rcall WaitMSSP | |
836 return | |
427 | 837 |
838 | |
839 END |