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