Mercurial > public > hwos_code
annotate src/i2c.asm @ 620:cd986267a5ca
potential compass bug "fixed"
author | heinrichsweikamp |
---|---|
date | Fri, 22 Feb 2019 16:30:05 +0100 |
parents | 7b3903536213 |
children | 1ad0531e9078 |
rev | line source |
---|---|
0 | 1 ;============================================================================= |
2 ; | |
604 | 3 ; File i2c.asm V2.99c |
0 | 4 ; |
560 | 5 ; I2C Interface |
6 ; | |
0 | 7 ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. |
8 ;============================================================================= | |
582 | 9 ; |
10 ; Compass0 | |
11 ; -------- | |
12 ; HMC5883L's read address (8-Bit): 0x3D | |
13 ; HMC5883L's write address (8-Bit): 0x3C | |
14 ; MMA8452Q's read address (8-Bit): 0x39 | |
15 ; MMA8452Q's write address (8-Bit): 0x38 | |
16 ; | |
17 ; Compass1 | |
18 ; -------- | |
19 ; LSM303D's read address (8-Bit): 0x3D | |
20 ; LSM303D's write address (8-Bit): 0x3C | |
21 ; | |
22 ; Compass2 | |
23 ; -------- | |
24 ; LSM303AGR's Compass read address (8-Bit): 0x3D | |
25 ; LSM303AGR's Compass write address (8-Bit): 0x3C | |
26 ; LSM303AGR's Acceleration read address (8-Bit): 0x33 | |
27 ; LSM303AGR's Acceleration write address (8-Bit): 0x32 | |
28 ; | |
29 ; RX Circuity | |
30 ; ----------- | |
31 ; RX Circuity read address (8-Bit): 0x51 | |
32 ; RX Circuity write address (8-Bit): 0x50 | |
33 ; | |
34 ; | |
35 | |
0 | 36 ; HISTORY |
37 ; 2012-08-22 : [mH] Creation | |
565 | 38 ; 2018-02-18 : [mH] Sync with hwOS Sport release |
0 | 39 |
40 | |
582 | 41 #include "hwos.inc" ; Mandatory header |
0 | 42 #include "wait.inc" |
113 | 43 #include "math.inc" |
560 | 44 #include "external_flash.inc" |
113 | 45 |
582 | 46 |
47 i2c CODE | |
48 | |
49 ;============================================================================= | |
0 | 50 |
51 I2C_TX: | |
582 | 52 movwf SSP1BUF |
53 rcall WaitMSSP | |
604 | 54 bra I2C_WaitforACK ; returns... |
0 | 55 |
604 | 56 I2C_TwoBytesRX_div16: ; get two bytes and divide lo:hi/16 (signed) |
57 rcall I2C_OneByteRX ; get one byte | |
58 movff SSP1BUF,hi ; data byte | |
59 rcall I2C_OneByteRX ; get one byte | |
60 movff SSP1BUF,lo ; data byte | |
582 | 61 I2C_TwoBytesRX_div16_2: ; divide lo:hi/16 (signed) only |
62 bcf STATUS,C | |
604 | 63 btfsc hi,7 ; copy sign bit to carry |
582 | 64 bsf STATUS,C |
65 rrcf hi ; /2 | |
66 rrcf lo | |
67 I2C_TwoBytesRX_div8_2: ; divide lo:hi/8 (signed) only | |
68 bcf STATUS,C | |
604 | 69 btfsc hi,7 ; copy sign bit to carry |
582 | 70 bsf STATUS,C |
71 rrcf hi ; /4 | |
72 rrcf lo | |
73 bcf STATUS,C | |
604 | 74 btfsc hi,7 ; copy sign bit to carry |
582 | 75 bsf STATUS,C |
76 rrcf hi ; /8 | |
77 rrcf lo | |
78 bcf STATUS,C | |
604 | 79 btfsc hi,7 ; copy sign bit to carry |
582 | 80 bsf STATUS,C |
81 rrcf hi ; /16 | |
82 rrcf lo | |
83 return | |
0 | 84 |
582 | 85 global I2C_RX_accelerometer |
0 | 86 I2C_RX_accelerometer: |
620 | 87 btfss compass_enabled ; Compass enabled? |
88 return ; No, return | |
604 | 89 btfsc compass_type2 ; compass2 ? |
90 bra I2C_RX_accelerometer_compass2 ; YES | |
91 btfsc compass_type ; compass1 ? | |
92 bra I2C_RX_accelerometer_compass1 ; YES | |
560 | 93 I2C_RX_accelerometer_compass0: |
604 | 94 bsf SSP1CON2,SEN ; start condition |
582 | 95 rcall WaitMSSP |
96 movlw 0x38 ; address | |
97 rcall I2C_TX | |
98 movlw 0x00 | |
99 rcall I2C_TX | |
604 | 100 bsf SSP1CON2,RSEN ; repeated start condition |
582 | 101 rcall WaitMSSP |
102 movlw 0x39 ; address | |
103 rcall I2C_TX | |
0 | 104 |
604 | 105 rcall I2C_OneByteRX ; get status byte |
582 | 106 movf SSP1BUF,W |
158 | 107 |
582 | 108 ; Non-flipped screen: |
109 ; Chip orientation on the PCB requires | |
604 | 110 ; Original = corrected |
582 | 111 ; x = -x |
112 ; y = -y | |
113 ; z = -z | |
0 | 114 |
582 | 115 ; Flipped screen: |
116 ; Chip orientation on the PCB requires | |
604 | 117 ; Original = corrected |
582 | 118 ; x = x |
119 ; y = y | |
120 ; z = -z | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
121 |
604 | 122 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
582 | 123 btfsc flip_screen ; 180° rotation ? |
604 | 124 bra I2C_RX_accelerometer2 ; YES |
125 comf hi ; 16 bit sign change | |
582 | 126 negf lo |
604 | 127 btfsc STATUS,C ; carry to propagate ? |
128 incf hi,F ; YES - do it | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
129 I2C_RX_accelerometer2: |
582 | 130 movff lo,accel_DX+0 |
131 movff hi,accel_DX+1 ; Copy result | |
0 | 132 |
582 | 133 rcall I2C_TwoBytesRX_div16 ; Get two bytes and divide /16 (signed) |
134 btfsc flip_screen ; 180° rotation ? | |
135 bra I2C_RX_accelerometer3 ; Yes | |
136 comf hi ; 16bit sign change. | |
137 negf lo | |
138 btfsc STATUS,C ; Carry to propagate ? | |
139 incf hi,F ; YES: do it. | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
140 I2C_RX_accelerometer3: |
582 | 141 movff lo,accel_DY+0 |
142 movff hi,accel_DY+1 ; Copy result | |
0 | 143 |
582 | 144 rcall I2C_OneByteRX ; Get one byte |
145 movff SSP1BUF,hi ; Data Byte | |
146 bsf SSP1CON2, RCEN ; Enable receive mode | |
147 rcall WaitMSSP | |
148 ; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+0)... | |
149 movff SSP1BUF,lo ; Data Byte | |
0 | 150 |
582 | 151 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only |
152 comf hi ; 16bit sign change. | |
153 negf lo | |
154 btfsc STATUS,C ; Carry to propagate ? | |
155 incf hi,F ; YES: do it. | |
156 movff lo,accel_DZ+0 | |
157 movff hi,accel_DZ+1 ; Copy result | |
0 | 158 |
582 | 159 bsf SSP1CON2,PEN ; Stop condition |
160 bra WaitMSSP ; (And return) | |
0 | 161 |
427 | 162 I2C_RX_accelerometer_compass1: |
582 | 163 bsf SSP1CON2,SEN ; Start condition |
164 rcall WaitMSSP | |
165 movlw 0x3C ; address | |
166 rcall I2C_TX | |
167 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) | |
168 rcall I2C_TX | |
169 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
170 rcall WaitMSSP | |
171 movlw 0x3D ; address | |
172 I2C_RX_accelerometer_compass1_xx: ; compass2 continues here... | |
173 rcall I2C_TX | |
174 | |
175 ; Non-flipped screen: | |
176 ; Chip orientation on the PCB requires | |
177 ; Original = Corrected | |
178 ; x = -x (Compass 1) | |
179 ; x = x (Compass 2) | |
180 ; y = -y | |
181 ; z = -z | |
182 | |
183 ; Flipped screen: | |
184 ; Chip orientation on the PCB requires | |
185 ; Original = Corrected | |
186 ; x = x (Compass 1) | |
187 ; x = -x (Compass 2) | |
188 ; y = y | |
189 ; z = -z | |
427 | 190 |
582 | 191 ; Dump the accelerator data |
192 rcall I2C_OneByteRX | |
193 movff SSP1BUF,lo ; accel_DX+0 | |
194 rcall I2C_OneByteRX | |
195 movff SSP1BUF,hi ;accel_DX+1 | |
196 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only | |
197 btfss compass_type2 ; compass 2? | |
198 bra I2C_RX_accelerometer1_c1 ; No, compass 1 | |
199 ; compass 2 | |
200 btfss flip_screen ; 180° rotation ? | |
201 bra I2C_RX_accelerometer2_c1 ; No, continue with normal compass1 routines for Y and Z | |
202 ; flipped compass 2, negate x | |
203 comf hi ; 16bit sign change. | |
204 negf lo | |
205 btfsc STATUS,C ; Carry to propagate ? | |
206 incf hi,F ; YES: do it. | |
207 bra I2C_RX_accelerometer2_c1 ; continue with normal compass1 routines for Y and Z | |
208 | |
209 I2C_RX_accelerometer1_c1: | |
210 btfsc flip_screen ; 180° rotation ? | |
211 bra I2C_RX_accelerometer2_c1 ; Yes | |
212 ; non-flipped compass 1, negate x | |
213 comf hi ; 16bit sign change. | |
214 negf lo | |
215 btfsc STATUS,C ; Carry to propagate ? | |
216 incf hi,F ; YES: do it. | |
427 | 217 I2C_RX_accelerometer2_c1: |
582 | 218 ; flipped compass 1, non-flipped compass 2 |
219 movff lo,accel_DX+0 | |
220 movff hi,accel_DX+1 ; Copy result | |
221 rcall I2C_OneByteRX | |
222 movff SSP1BUF,lo ; accel_DY+0 | |
223 rcall I2C_OneByteRX | |
224 movff SSP1BUF,hi ; accel_DY+1 | |
225 | |
226 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only | |
227 btfsc flip_screen ; 180° rotation ? | |
228 bra I2C_RX_accelerometer3_c1 ; Yes | |
229 comf hi ; 16bit sign change. | |
230 negf lo | |
231 btfsc STATUS,C ; Carry to propagate ? | |
232 incf hi,F ; YES: do it. | |
427 | 233 I2C_RX_accelerometer3_c1: |
582 | 234 movff lo,accel_DY+0 |
235 movff hi,accel_DY+1 ; Copy result | |
427 | 236 |
582 | 237 rcall I2C_OneByteRX |
238 movff SSP1BUF,lo ;accel_DZ+0 | |
239 bsf SSP1CON2, RCEN ; Enable receive mode | |
240 rcall WaitMSSP | |
241 ; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+1)... | |
242 movff SSP1BUF,hi ;accel_DZ+1 | |
243 bsf SSP1CON2,PEN ; Stop condition | |
244 rcall WaitMSSP | |
245 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only | |
246 comf hi ; 16bit sign change for Z | |
247 negf lo | |
248 btfsc STATUS,C ; Carry to propagate ? | |
249 incf hi,F ; YES: do it. | |
250 movff lo,accel_DZ+0 | |
251 movff hi,accel_DZ+1 ; Copy result | |
252 return | |
253 | |
560 | 254 I2C_RX_accelerometer_compass2: |
582 | 255 bsf SSP1CON2,SEN ; Start condition |
256 rcall WaitMSSP | |
257 movlw 0x32 ; address | |
258 rcall I2C_TX | |
259 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) | |
260 rcall I2C_TX | |
261 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
262 rcall WaitMSSP | |
263 movlw 0x33 ; address | |
264 bra I2C_RX_accelerometer_compass1_xx | |
265 | |
0 | 266 I2C_OneByteRX: |
582 | 267 bsf SSP1CON2,RCEN ; Enable receive mode |
268 rcall WaitMSSP | |
269 bsf SSP1CON2,ACKEN ; Master acknowledge | |
270 bra WaitMSSP ; And return! | |
0 | 271 |
582 | 272 global I2C_RX_compass |
0 | 273 I2C_RX_compass: |
620 | 274 btfss compass_enabled ; Compass enabled? |
275 return ; No, return | |
276 | |
582 | 277 btfsc compass_type2 ; compass2 |
278 bra I2C_RX_compass2 ; yes | |
279 btfsc compass_type ; compass1? | |
280 bra I2C_RX_compass1 ; yes | |
560 | 281 I2C_RX_compass0: |
582 | 282 bsf SSP1CON2,SEN ; Start condition |
283 rcall WaitMSSP | |
284 movlw 0x3C ; address | |
285 rcall I2C_TX | |
286 movlw 0x03 | |
287 rcall I2C_TX | |
288 bsf SSP1CON2,PEN ; Stop condition | |
289 rcall WaitMSSP | |
0 | 290 |
582 | 291 bcf PIR1,SSP1IF |
292 bsf SSP1CON2,SEN ; Start condition | |
293 rcall WaitMSSP | |
294 movlw 0x3D ; address | |
295 rcall I2C_TX | |
0 | 296 |
582 | 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 | |
0 | 304 |
582 | 305 ; Non-flipped screen |
306 ; Chip orientation on the PCB requires | |
307 ; Original = Corrected | |
308 ; x = -y | |
309 ; z = z | |
310 ; y = x | |
0 | 311 |
582 | 312 ; Flipped screen |
313 ; Chip orientation on the PCB requires | |
314 ; Original = Corrected | |
315 ; x = y | |
316 ; z = z | |
317 ; y = -x | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
318 |
582 | 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 | |
323 btfsc flip_screen ; 180° rotation ? | |
324 bra I2C_RX_compass0_2 ; Yes | |
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. | |
560 | 330 I2C_RX_compass0_2: |
582 | 331 banksel common |
332 rcall I2C_OneByteRX ; Get one byte | |
333 movff SSP1BUF,compass_DZ+1 ; Data Byte | |
334 rcall I2C_OneByteRX ; Get one byte | |
335 movff SSP1BUF,compass_DZ+0 ; Data Byte | |
336 rcall I2C_OneByteRX ; Get one byte | |
337 movff SSP1BUF,compass_DX+1 ; Data Byte | |
338 bsf SSP1CON2, RCEN ; Enable receive mode | |
339 rcall WaitMSSP | |
340 movff SSP1BUF,compass_DX+0 ; Data Byte | |
341 bsf SSP1CON2,PEN ; Stop condition | |
342 rcall WaitMSSP | |
343 btfss flip_screen ; 180° rotation ? | |
344 return ; No, done. | |
345 ; Yes, flip X | |
346 banksel compass_DX | |
347 comf compass_DX+1 ; 16bit sign change. | |
348 negf compass_DX+0 | |
349 btfsc STATUS,C ; Carry to propagate ? | |
350 incf compass_DX+1,F ; YES: do it. | |
351 banksel common | |
352 return | |
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 ;rcall WaitMSSP ; Needed? (mH) | |
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 | |
427 | 382 I2C_RX_compass1_1: |
582 | 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. | |
427 | 398 I2C_RX_compass1_2: |
582 | 399 banksel common |
400 rcall I2C_OneByteRX ; Get one byte | |
401 movff SSP1BUF,lo ; Data Byte | |
402 bsf SSP1CON2, RCEN ; Enable receive 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 bra WaitMSSP ;(And return) | |
560 | 410 |
582 | 411 I2C_RX_compass2: ; newest compass |
412 bsf SSP1CON2,SEN ; Start condition | |
413 rcall WaitMSSP | |
414 movlw 0x3C ; address | |
415 rcall I2C_TX | |
416 movlw 0xE8 ; 0x68 with auto-increment (MSB=1) | |
417 rcall I2C_TX | |
418 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
419 rcall WaitMSSP | |
420 movlw 0x3D ; address | |
421 rcall I2C_TX | |
422 ; rcall WaitMSSP | |
423 rcall I2C_OneByteRX ; Get one byte | |
424 movff SSP1BUF,lo ; Data Byte | |
425 rcall I2C_OneByteRX ; Get one byte | |
426 movff SSP1BUF,hi ; Data Byte | |
427 ; rcall I2C_TwoBytesRX_div8_2 | |
428 btfsc flip_screen ; 180° rotation ? | |
429 bra I2C_RX_compass2_1 ; Yes, do nothing with X | |
430 ; No, flip X | |
431 comf hi ; 16bit sign change. | |
432 negf lo | |
433 btfsc STATUS,C ; Carry to propagate ? | |
434 incf hi,F ; YES: do it. | |
435 I2C_RX_compass2_1: | |
436 movff lo,compass_DX+0 | |
437 movff hi,compass_DX+1 | |
438 rcall I2C_OneByteRX ; Get one byte | |
439 movff SSP1BUF,lo ; Data Byte | |
440 rcall I2C_OneByteRX ; Get one byte | |
441 movff SSP1BUF,hi ; Data Byte | |
442 ; rcall I2C_TwoBytesRX_div8_2 | |
443 btfss flip_screen ; 180° rotation ? | |
444 bra I2C_RX_compass2_2 ; No, do nothing with Y | |
445 ; Yes, flip Y | |
446 comf hi ; 16bit sign change. | |
447 negf lo | |
448 btfsc STATUS,C ; Carry to propagate ? | |
449 incf hi,F ; YES: do it. | |
560 | 450 I2C_RX_compass2_2: |
582 | 451 movff lo,compass_DY+0 |
452 movff hi,compass_DY+1 | |
453 rcall I2C_OneByteRX ; Get one byte | |
454 movff SSP1BUF,lo ; Data Byte | |
455 rcall I2C_OneByteRX ; Get one byte | |
456 movff SSP1BUF,hi ; Data Byte | |
457 ; rcall I2C_TwoBytesRX_div8_2 | |
458 movff lo,compass_DZ+0 | |
459 movff hi,compass_DZ+1 | |
460 bsf SSP1CON2,PEN ; Stop condition | |
461 bra WaitMSSP ;(And return) | |
462 | |
463 | |
464 global I2C_init_compass | |
0 | 465 I2C_init_compass: |
582 | 466 bsf compass_enabled |
467 bcf compass_type2 | |
468 ; probe compass 2 | |
469 bsf SSP1CON2,SEN ; Start condition | |
470 rcall WaitMSSP | |
471 movlw 0x32 ; Address byte + Write bit | |
472 movwf SSP1BUF ; control byte | |
473 rcall WaitMSSP | |
474 btfss SSP1CON2,ACKSTAT ; ACK? | |
475 bsf compass_type2 ; ACK send. compass2 present | |
476 bsf SSP1CON2,PEN ; Stop condition | |
477 rcall WaitMSSP | |
427 | 478 |
582 | 479 btfsc compass_type2 |
480 bra I2C_init_compass2 ; Compass2 | |
481 ; Check for compass0 or compass1... | |
482 bsf compass_type ; set flag | |
483 bsf SSP1CON2,SEN ; Start condition | |
484 rcall WaitMSSP | |
485 movlw 0x3C ; address | |
486 rcall I2C_TX | |
487 movlw 0x0F | |
488 rcall I2C_TX | |
489 bsf SSP1CON2,PEN ; Stop condition | |
490 rcall WaitMSSP | |
491 bcf PIR1,SSP1IF | |
492 bsf SSP1CON2,SEN ; Start condition | |
493 rcall WaitMSSP | |
494 movlw 0x3D ; address | |
495 rcall I2C_TX | |
496 rcall I2C_OneByteRX ; Get one byte | |
497 movlw 0x49 ; 0x49 = Compass1 | |
498 cpfseq SSP1BUF | |
499 bcf compass_type ; clear flag | |
500 bsf SSP1CON2,PEN ; Stop condition | |
501 rcall WaitMSSP | |
502 | |
503 btfsc compass_type ; compass1? | |
504 bra I2C_init_compass1 ; yes | |
620 | 505 |
506 ; Check for compass0 | |
507 bsf SSP1CON2,SEN ; Start condition | |
508 rcall WaitMSSP | |
509 movlw 0x3C ; address | |
510 rcall I2C_TX | |
511 movlw 0x10 | |
512 rcall I2C_TX | |
513 bsf SSP1CON2,PEN ; Stop condition | |
514 rcall WaitMSSP | |
515 bcf PIR1,SSP1IF | |
516 bsf SSP1CON2,SEN ; Start condition | |
517 rcall WaitMSSP | |
518 movlw 0x3D ; address | |
519 rcall I2C_TX | |
520 rcall I2C_OneByteRX ; Get one byte | |
521 movlw "H" ; ASCI "H" = Compass0 | |
522 cpfseq SSP1BUF | |
523 bcf compass_enabled ; clear enable flag, neither Compass2, 1 or 0 was found properly | |
524 bsf SSP1CON2,PEN ; Stop condition | |
525 rcall WaitMSSP | |
526 | |
527 | |
427 | 528 ; init compass0 |
620 | 529 btfss compass_enabled ; Compass enabled? |
530 return ; No, return | |
582 | 531 bsf SSP1CON2,SEN ; Start condition |
532 rcall WaitMSSP | |
533 movlw 0x3C ; address | |
534 rcall I2C_TX | |
535 movlw 0x00 | |
536 rcall I2C_TX | |
537 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) | |
538 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged | |
539 rcall I2C_TX | |
20 | 540 I2C_init_compass_common: |
582 | 541 movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) |
542 swapf i2c_temp1,F | |
543 comf i2c_temp1,F | |
544 bcf STATUS,C | |
545 rlcf i2c_temp1 | |
546 movf i2c_temp1,W | |
547 clrf i2c_temp1 | |
548 rcall I2C_TX | |
549 movlw b'00000000' ; Continuous Mode | |
550 rcall I2C_TX | |
551 bsf SSP1CON2,PEN ; Stop condition | |
552 bra WaitMSSP ; (And return) | |
0 | 553 |
427 | 554 I2C_init_compass1: |
582 | 555 bsf SSP1CON2,SEN ; Start condition |
556 rcall WaitMSSP | |
557 movlw 0x3C ; address | |
558 rcall I2C_TX | |
559 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
560 rcall I2C_TX | |
561 movlw b'00000000' ; CTRL0 | |
562 rcall I2C_TX | |
563 movlw b'00101111' ; CTRL1 (6,25Hz, BDU=0, x,y,z = ON) | |
564 rcall I2C_TX | |
565 movlw b'11000000' ; CTRL2 (50Hz, +/-2g, | |
566 rcall I2C_TX | |
567 movlw b'00000000' ; CTRL3 | |
568 rcall I2C_TX | |
569 movlw b'00000000' ; CTRL4 | |
570 rcall I2C_TX | |
571 movlw b'01100100' ; CTRL5 HIGH res, 6,25Hz | |
572 rcall I2C_TX | |
429 | 573 init_compass1_common: |
582 | 574 movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) +++ |
575 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) | |
576 dcfsnz i2c_temp1,F ; = 1? | |
577 movlw b'01100000' ; Yes, CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) | |
578 dcfsnz i2c_temp1,F ; = 2? | |
579 movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss) | |
580 dcfsnz i2c_temp1,F ; = 3? | |
581 movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss) | |
582 dcfsnz i2c_temp1,F ; = 4? | |
583 movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss) | |
584 dcfsnz i2c_temp1,F ; = 5? | |
585 movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss) | |
586 dcfsnz i2c_temp1,F ; = 6? | |
587 movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss) | |
588 dcfsnz i2c_temp1,F ; = 7? | |
589 movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss) | |
590 rcall I2C_TX | |
591 movlw b'00000000' ; CTRL7 Continuous Mode | |
592 rcall I2C_TX | |
593 bsf SSP1CON2,PEN ; Stop condition | |
594 bra WaitMSSP ; (And return) | |
595 | |
560 | 596 I2C_init_compass2: |
608 | 597 bsf SSP1CON2,SEN ; Start condition |
598 rcall WaitMSSP | |
599 movlw 0x3C ; address | |
600 rcall I2C_TX | |
601 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) | |
602 rcall I2C_TX | |
603 movlw b'00000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 | |
604 rcall I2C_TX | |
605 movlw b'00000000' ; CFG_REG_B_M (Low-Pass Filter off) 0x61 (set pulse is released every 63 ODR) | |
606 rcall I2C_TX | |
607 movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62 | |
608 rcall I2C_TX | |
609 bsf SSP1CON2,PEN ; Stop condition | |
610 bra WaitMSSP ;(And return) | |
582 | 611 |
612 | |
613 global I2C_sleep_compass | |
0 | 614 I2C_sleep_compass: |
620 | 615 btfss compass_enabled ; Compass enabled? |
616 return ; No, return | |
582 | 617 bcf compass_enabled |
618 btfsc compass_type2 ; compass2? | |
619 bra I2C_sleep_compass2 ; yes | |
620 btfsc compass_type ; compass1? | |
621 bra I2C_sleep_compass1 ; yes | |
560 | 622 I2C_sleep_compass0: |
582 | 623 bsf SSP1CON2,SEN ; Start condition |
624 rcall WaitMSSP | |
625 movlw 0x3C ; address | |
626 rcall I2C_TX | |
627 movlw 0x00 | |
628 rcall I2C_TX | |
629 movlw b'01101000' ; ConfigA | |
630 rcall I2C_TX | |
631 movlw b'00100000' ; ConfigB | |
632 rcall I2C_TX | |
633 movlw b'00000010' ; Idle Mode | |
634 rcall I2C_TX | |
635 bsf SSP1CON2,PEN ; Stop condition | |
636 bra WaitMSSP ; (And return) | |
0 | 637 |
427 | 638 I2C_sleep_compass1: |
582 | 639 bsf SSP1CON2,SEN ; Start condition |
640 rcall WaitMSSP | |
641 movlw 0x3C ; address | |
642 rcall I2C_TX | |
643 movlw 0x20 ; CTRL_REG1 | |
644 rcall I2C_TX | |
645 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor Power-down mode | |
646 rcall I2C_TX | |
647 bsf SSP1CON2,PEN ; Stop condition | |
648 rcall WaitMSSP | |
649 bsf SSP1CON2,SEN ; Start condition | |
650 rcall WaitMSSP | |
651 movlw 0x3C ; address | |
652 rcall I2C_TX | |
653 movlw 0x26 ; CTRL_REG7 | |
654 rcall I2C_TX | |
655 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor Power-down mode | |
656 rcall I2C_TX | |
657 bsf SSP1CON2,PEN ; Stop condition | |
658 bra WaitMSSP ;(And return) | |
560 | 659 |
660 I2C_sleep_compass2: | |
608 | 661 ; magnetic |
662 bsf SSP1CON2,SEN ; Start condition | |
663 rcall WaitMSSP | |
664 movlw 0x3C ; address | |
665 rcall I2C_TX | |
666 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) | |
667 rcall I2C_TX | |
668 movlw b'00000011' ; CFG_REG_A_M (Idle mode) 0x60 | |
669 rcall I2C_TX | |
670 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) | |
671 rcall I2C_TX | |
672 movlw b'01010001' ; CFG_REG_C_M 0x62 | |
673 rcall I2C_TX | |
674 movlw b'00000000' ; INT_CTRL_REG_M 0x63 | |
675 rcall I2C_TX | |
582 | 676 |
608 | 677 bsf SSP1CON2,PEN ; Stop condition |
678 bra WaitMSSP ; (And return) | |
679 | |
560 | 680 I2C_sleep_accelerometer2: |
608 | 681 ; accelerometer |
682 bsf SSP1CON2,SEN ; Start condition | |
683 rcall WaitMSSP | |
684 movlw 0x32 ; address | |
685 rcall I2C_TX | |
686 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
687 rcall I2C_TX | |
688 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) 0x1F | |
689 rcall I2C_TX | |
690 movlw b'00000000' ; CTRL_REG1_A (All off) 0x20 | |
691 rcall I2C_TX | |
692 bsf SSP1CON2,PEN ; Stop condition | |
693 bra WaitMSSP ; (And return) | |
0 | 694 |
615 | 695 WaitMSSP: |
696 decfsz i2c_temp1,F ; check for timeout during I2C action | |
697 bra WaitMSSP2 | |
698 bra I2CFail ; timeout occurred | |
699 WaitMSSP2: | |
700 btfss PIR1,SSP1IF | |
701 bra WaitMSSP | |
702 clrf i2c_temp1 | |
703 bcf PIR1,SSP1IF | |
704 return | |
705 | |
706 I2C_WaitforACK: | |
707 btfss SSP1CON2,ACKSTAT ; checks for ACK bit from slave | |
708 return | |
709 I2CFail: | |
710 rcall I2CReset ; I2C Reset | |
711 bcf PIR1,SSP1IF | |
712 clrf i2c_temp1 | |
713 bsf i2c_error_flag ; set error flag | |
714 return | |
715 | |
716 I2CReset: ; something went wrong (slave holds SDA low?) | |
717 clrf SSP1CON1 ; wake-up slave and reset entire module | |
718 clrf SSP1CON2 | |
719 clrf SSP1STAT | |
720 bcf TRISC,3 ; SCL OUTPUT | |
721 bsf TRISC,4 ; SDA input | |
722 bcf PORTC,3 | |
723 movlw d'9' | |
724 movwf i2c_temp1 ; clock-out 9 clock cycles manually | |
725 I2CReset_1: | |
726 bsf PORTC,3 ; SCL = 1 | |
727 nop | |
728 nop | |
729 nop | |
730 nop | |
731 btfsc PORTC,4 ; SDA = 1 ? | |
732 bra I2CReset_2 ; YES - =1, SDA has been released from slave | |
733 bcf PORTC,3 ; NO - set SCL = 0 | |
734 nop | |
735 nop | |
736 bcf PORTC,3 | |
737 nop | |
738 nop | |
739 decfsz i2c_temp1,F | |
740 bra I2CReset_1 ; check for nine clock cycles | |
741 I2CReset_2: | |
742 bsf TRISC,3 ; SCL Input | |
743 clrf SSP1CON1 ; setup I²C mode | |
744 WAITMS d'10' ; reset-timeout for I2C devices | |
745 movlw b'00000000' ; with slew rate control | |
746 movwf SSP1STAT | |
747 movlw b'00101000' | |
748 movwf SSP1CON1 | |
749 movlw b'00000000' | |
750 movwf SSP1CON2 | |
751 movlw 0x27 | |
752 movwf SSP1ADD | |
753 return | |
754 | |
582 | 755 global I2C_init_accelerometer |
0 | 756 I2C_init_accelerometer: |
620 | 757 btfss compass_enabled ; Compass enabled? |
758 return ; No, return | |
759 | |
582 | 760 btfsc compass_type2 ; compass2? |
761 bra I2C_init_accelerometer2 ; Yes. | |
560 | 762 |
582 | 763 btfsc compass_type ; compass1? |
764 return ; yes, ignore | |
427 | 765 |
582 | 766 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode |
0 | 767 |
582 | 768 bsf SSP1CON2,SEN ; Start condition |
769 rcall WaitMSSP | |
770 movlw 0x38 ; address | |
771 rcall I2C_TX | |
772 movlw 0x0E ; XYZ_DATA_CFG | |
773 rcall I2C_TX | |
774 movlw b'00000000' ; High pass Filter=0 , +/- 2g range | |
775 rcall I2C_TX | |
776 bsf SSP1CON2,PEN ; Stop condition | |
777 rcall WaitMSSP | |
0 | 778 |
582 | 779 bsf SSP1CON2,SEN ; Start condition |
780 rcall WaitMSSP | |
781 movlw 0x38 ; address | |
782 rcall I2C_TX | |
783 movlw 0x2A ; CTRL_REG1 | |
784 rcall I2C_TX | |
785 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode | |
786 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode | |
787 rcall I2C_TX | |
788 movlw b'00000010' ; CTRL_REG2: High Res in Active mode | |
789 rcall I2C_TX | |
790 bsf SSP1CON2,PEN ; Stop condition | |
791 rcall WaitMSSP | |
0 | 792 |
582 | 793 bsf SSP1CON2,SEN ; Start condition |
794 rcall WaitMSSP | |
795 movlw 0x38 ; address | |
796 rcall I2C_TX | |
797 movlw 0x2A ; CTRL_REG1 | |
798 rcall I2C_TX | |
799 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode | |
800 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode | |
801 rcall I2C_TX | |
802 bsf SSP1CON2,PEN ; Stop condition | |
803 bra WaitMSSP ; (And return) | |
804 | |
560 | 805 I2C_init_accelerometer2: |
582 | 806 bsf SSP1CON2,SEN ; Start condition |
807 rcall WaitMSSP | |
808 movlw 0x32 ; address | |
809 rcall I2C_TX | |
810 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
811 rcall I2C_TX | |
812 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) | |
813 rcall I2C_TX | |
814 movlw b'01010111' ; CTRL_REG1_A (100Hz, x,y,z = ON) | |
815 rcall I2C_TX | |
816 movlw b'00000000' ; CTRL_REG2_A | |
817 rcall I2C_TX | |
818 ; movlw b'00000000' ; CTRL_REG3_A | |
819 ; rcall I2C_TX | |
820 ; movlw b'00000000' ; CTRL_REG4_A (BDU=0, +/-2g, | |
821 ; rcall I2C_TX | |
822 ; movlw b'00000000' ; CTRL_REG5_A | |
823 ; rcall I2C_TX | |
824 bsf SSP1CON2,PEN ; Stop condition | |
825 bra WaitMSSP ; (And return) | |
0 | 826 |
582 | 827 global I2C_sleep_accelerometer |
0 | 828 I2C_sleep_accelerometer: |
582 | 829 btfsc compass_type2 ; Compass2 |
830 bra I2C_sleep_accelerometer2 ; Yes | |
831 btfsc compass_type ; compass1? | |
832 return ; yes, ignore | |
427 | 833 |
582 | 834 bsf SSP1CON2,SEN ; Start condition |
835 rcall WaitMSSP | |
836 movlw 0x38 ; address | |
837 rcall I2C_TX | |
838 movlw 0x2A ; CTRL_REG1 | |
839 rcall I2C_TX | |
840 movlw b'00000000' ; St. By Mode | |
841 rcall I2C_TX | |
842 bsf SSP1CON2,PEN ; Stop condition | |
843 bra WaitMSSP ; (And return) | |
844 | |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
845 lt2942_init_again: |
582 | 846 clrf i2c_temp1 |
847 movlw 0x02 ; Point to accumulated charge registers | |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
848 rcall I2C_TX_GAUGE |
582 | 849 movff battery_acumulated_charge+1,SSP1BUF ; Data Byte |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
850 rcall WaitMSSP |
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
851 rcall I2C_WaitforACK |
582 | 852 movff battery_acumulated_charge+0,SSP1BUF ; Data Byte |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
853 rcall WaitMSSP |
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
854 rcall I2C_WaitforACK |
582 | 855 bsf SSP1CON2,PEN ; Stop condition |
560 | 856 rcall WaitMSSP |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
857 movff battery_acumulated_charge+1,sub_a+1 |
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
858 movff battery_acumulated_charge+0,sub_a+0 |
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
859 ; and init again... |
560 | 860 |
582 | 861 global lt2942_init |
862 lt2942_init: ; Setup Control register B | |
863 clrf i2c_temp1 | |
864 movlw 0x01 ; Point to control reg B | |
467 | 865 rcall I2C_TX_GAUGE |
582 | 866 movlw b'11111000' ; Automatic conversion every two seconds |
867 movff WREG, SSP1BUF ; Data Byte | |
113 | 868 rcall WaitMSSP |
869 rcall I2C_WaitforACK | |
582 | 870 bsf SSP1CON2,PEN ; Stop condition |
871 bra WaitMSSP ; (And return) | |
113 | 872 |
873 global lt2942_get_status | |
582 | 874 lt2942_get_status: ; Read status register |
875 bcf battery_gauge_available ; Clear flag | |
876 clrf i2c_temp1 | |
877 movlw 0x00 ; Point to Status reg | |
467 | 878 rcall I2C_TX_GAUGE |
879 rcall I2C_RX_GAUGE | |
113 | 880 movff SSP1BUF,WREG |
582 | 881 btfss WREG,7 ; 2942 found? |
882 bsf battery_gauge_available ; Yes, set flag | |
883 bsf SSP1CON2,PEN ; Stop condition | |
884 bra WaitMSSP ; (And return) | |
113 | 885 |
886 | |
887 global lt2942_get_voltage | |
582 | 888 lt2942_get_voltage: ; Read battery voltage registers |
889 clrf i2c_temp1 | |
890 movlw 0x08 ; Point to voltage registers | |
448 | 891 rcall I2C_TX_GAUGE |
892 rcall I2C_RX_GAUGE | |
582 | 893 bsf SSP1CON2,ACKEN ; Master acknowledge |
113 | 894 rcall WaitMSSP |
895 movff SSP1BUF,xA+1 | |
582 | 896 bsf SSP1CON2, RCEN ; Enable receive mode |
113 | 897 rcall WaitMSSP |
898 movff SSP1BUF,xA+0 | |
582 | 899 bsf SSP1CON2,PEN ; Stop condition |
113 | 900 rcall WaitMSSP |
901 | |
902 ; banksel common | |
582 | 903 ; xA:2 loaded with raw values |
904 movlw LOW .6000 | |
905 movwf xB+0 | |
906 movlw HIGH .6000 | |
907 movwf xB+1 | |
908 call mult16x16 ; xA*xB=xC | |
113 | 909 |
618 | 910 ; xC+3:xC+2 -> Result in mV |
113 | 911 |
582 | 912 ; Update battery voltage in mV |
618 | 913 movff xC+3,batt_voltage+1 |
914 movff xC+2,batt_voltage+0 | |
466 | 915 |
582 | 916 tstfsz batt_voltage+1 ; <256mV? |
917 return ; No, done. | |
918 bra lt2942_init ;(and return) | |
113 | 919 |
615 | 920 global lt2942_get_temperature |
921 lt2942_get_temperature: ; Read temperature registers | |
922 clrf i2c_temp1 | |
923 movlw 0x0C ; Point to temperature registers | |
924 call I2C_TX_GAUGE | |
925 call I2C_RX_GAUGE | |
926 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
927 rcall WaitMSSP | |
928 movff SSP1BUF,xA+1 | |
929 bsf SSP1CON2, RCEN ; Enable recieve mode | |
930 rcall WaitMSSP | |
931 movff SSP1BUF,xA+0 | |
932 bsf SSP1CON2,PEN ; Stop condition | |
933 rcall WaitMSSP | |
934 | |
935 ; banksel common | |
936 ; xA:2 loaded with raw values | |
937 movlw LOW .6000 | |
938 movwf xB+0 | |
939 movlw HIGH .6000 | |
940 movwf xB+1 | |
941 call mult16x16 ;xA*xB=xC | |
942 | |
618 | 943 ; xC+3:xC+2 -> Result in 0.1K |
615 | 944 |
616 | 945 movlw LOW max_allowed_battery_temp ; in 0.1K |
615 | 946 movwf sub_a+0 |
947 movlw HIGH max_allowed_battery_temp | |
948 movwf sub_a+1 | |
618 | 949 movff xC+3,sub_b+1 |
950 movff xC+2,sub_b+0 | |
615 | 951 call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) |
952 btfss neg_flag | |
953 return ; temp ok, return | |
954 ; too hot, disable charge if currently charging | |
955 btfss cc_active | |
956 return ; Not charging, return | |
957 ; charging: Disable now | |
958 bsf charge_disable | |
959 bcf TRISE,2 | |
960 bsf battery_overtemp ; =1: The battery was charged and temp was too high (Only cleared on POR) | |
961 return | |
113 | 962 |
963 global lt2942_get_accumulated_charge | |
582 | 964 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent |
965 clrf i2c_temp1 | |
966 movlw 0x00 ; Point to status register | |
467 | 967 rcall I2C_TX_GAUGE |
968 rcall I2C_RX_GAUGE | |
582 | 969 bsf SSP1CON2,ACKEN ; Master acknowledge |
113 | 970 rcall WaitMSSP |
466 | 971 movff SSP1BUF,gauge_status_byte |
972 | |
582 | 973 bsf SSP1CON2, RCEN ; Enable receive mode |
974 rcall WaitMSSP ; Dummy read (Control byte) | |
467 | 975 movf SSP1BUF,W |
582 | 976 bsf SSP1CON2,ACKEN ; Master acknowledge |
467 | 977 rcall WaitMSSP |
582 | 978 |
979 bsf SSP1CON2, RCEN ; Enable receive mode | |
113 | 980 rcall WaitMSSP |
466 | 981 movff SSP1BUF,sub_a+1 |
582 | 982 bsf SSP1CON2,ACKEN ; Master acknowledge |
467 | 983 rcall WaitMSSP |
582 | 984 |
985 bsf SSP1CON2, RCEN ; Enable receive mode | |
466 | 986 rcall WaitMSSP |
987 movff SSP1BUF,sub_a+0 | |
582 | 988 bsf SSP1CON2,PEN ; Stop condition |
113 | 989 rcall WaitMSSP |
582 | 990 |
991 movff gauge_status_byte,sub_b+0 ; copy into bank common | |
992 btfsc sub_b+0,0 ; =1: UVLO Event | |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
993 rcall lt2942_init_again |
113 | 994 |
582 | 995 movff sub_a+1,battery_acumulated_charge+1 ; Save raw value |
996 movff sub_a+0,battery_acumulated_charge+0 ; Save raw value | |
997 | |
998 ; Compute batt_percent | |
999 ; (charge-battery_offset)/365 | |
1000 movff battery_offset+0,sub_b+0 | |
1001 movff battery_offset+1,sub_b+1 | |
1002 call subU16 ; sub_c = sub_a - sub_b (with signed values) | |
113 | 1003 |
582 | 1004 clrf batt_percent ; Set to zero |
1005 btfsc neg_flag ; result negative? | |
1006 bra lt2942_set_to_zero_percent ; Yes, keep LT2942 at zero percent and return | |
113 | 1007 |
582 | 1008 ; > Zero, set batt_percent properly |
1009 movff sub_c+0,xA+0 | |
1010 movff sub_c+1,xA+1 | |
1011 movff battery_capacity+0,xB+0 | |
1012 movff battery_capacity+1,xB+1 | |
604 | 1013 call div16x16 ; xC = xA / xB with xA as remainder |
582 | 1014 movff xC+0,batt_percent |
1015 return | |
113 | 1016 |
449 | 1017 lt2942_set_to_zero_percent: |
582 | 1018 clrf i2c_temp1 |
1019 movlw 0x02 ; Point to accumulated charge registers | |
449 | 1020 rcall I2C_TX_GAUGE |
1021 movff battery_offset+1,SSP1BUF | |
1022 rcall WaitMSSP | |
1023 rcall I2C_WaitforACK | |
1024 movff battery_offset+0,SSP1BUF | |
1025 rcall WaitMSSP | |
1026 rcall I2C_WaitforACK | |
582 | 1027 bsf SSP1CON2,PEN ; Stop condition |
1028 bra WaitMSSP ; (and return) | |
449 | 1029 |
113 | 1030 global lt2942_charge_done |
582 | 1031 lt2942_charge_done: ; Reset accumulating registers to 0xFFFF |
1032 clrf i2c_temp1 | |
1033 movlw 0x02 ; Point to accumulated charge registers | |
448 | 1034 rcall I2C_TX_GAUGE |
582 | 1035 setf SSP1BUF ; Data Byte |
113 | 1036 rcall WaitMSSP |
1037 rcall I2C_WaitforACK | |
582 | 1038 setf SSP1BUF ; Data Byte |
113 | 1039 rcall WaitMSSP |
1040 rcall I2C_WaitforACK | |
582 | 1041 bsf SSP1CON2,PEN ; Stop condition |
1042 bra WaitMSSP ; (and return) | |
113 | 1043 |
582 | 1044 I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC |
1045 movwf i2c_temp2 ; Data byte | |
1046 bsf SSP1CON2,SEN ; Start condition | |
113 | 1047 rcall WaitMSSP |
582 | 1048 movlw b'11001000' ; Address byte + Write bit |
1049 movwf SSP1BUF ; control byte | |
113 | 1050 rcall WaitMSSP |
1051 rcall I2C_WaitforACK | |
582 | 1052 movf i2c_temp2,W |
1053 bra I2C_TX ; (and return) | |
1054 | |
113 | 1055 I2C_RX_GAUGE: |
582 | 1056 bsf SSP1CON2,SEN ; Start condition |
113 | 1057 rcall WaitMSSP |
582 | 1058 movlw b'11001001' ; Address byte + Read bit |
1059 movwf SSP1BUF ; control byte | |
113 | 1060 rcall WaitMSSP |
1061 rcall I2C_WaitforACK | |
582 | 1062 bsf SSP1CON2, RCEN ; Enable receive mode |
1063 bra WaitMSSP ; (and return) | |
1064 | |
1065 | |
604 | 1066 ;----------------------------------------------------------------------------- |
1067 ; Transmitter Functions | |
1068 | |
1069 IFDEF _rx_functions | |
1070 | |
560 | 1071 global I2C_probe_OSTC_rx |
1072 I2C_probe_OSTC_rx: | |
604 | 1073 movlw .5 |
1074 movwf lo_temp | |
1075 I2C_probe_OSTC_rx_1: | |
582 | 1076 bsf SSP1CON2,SEN ; Start condition |
560 | 1077 rcall WaitMSSP |
582 | 1078 movlw 0x50 ; Address byte + Write bit |
1079 movwf SSP1BUF ; control byte | |
560 | 1080 rcall WaitMSSP |
582 | 1081 btfss SSP1CON2,ACKSTAT ; ACK? |
604 | 1082 bsf ostc_rx_present ; ACK sent - OSTC_RX present! |
582 | 1083 bsf SSP1CON2,PEN ; Stop condition |
560 | 1084 rcall WaitMSSP |
582 | 1085 btfss ostc_rx_present ; Do we have the RX? |
1086 return ; No, Done. | |
560 | 1087 WAITMS .1 |
582 | 1088 bsf SSP1CON2,SEN ; Start condition |
560 | 1089 rcall WaitMSSP |
582 | 1090 movlw 0x50 ; Address byte + Write bit |
1091 movwf SSP1BUF ; control byte | |
560 | 1092 rcall WaitMSSP |
1093 rcall I2C_WaitforACK | |
1094 movlw 0x1B | |
582 | 1095 movwf SSP1BUF ; Data Byte (Get firmware) |
560 | 1096 rcall WaitMSSP |
1097 rcall I2C_WaitforACK | |
582 | 1098 bsf SSP1CON2,PEN ; Stop condition |
560 | 1099 rcall WaitMSSP |
1100 WAITMS .1 | |
582 | 1101 bsf SSP1CON2,SEN ; Start condition |
560 | 1102 rcall WaitMSSP |
582 | 1103 movlw 0x51 ; Address byte + Read bit |
1104 movwf SSP1BUF ; control byte | |
560 | 1105 rcall WaitMSSP |
582 | 1106 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1107 rcall WaitMSSP |
1108 movff SSP1BUF,rx_firmware+0 | |
582 | 1109 bsf SSP1CON2,ACKEN ; Master acknowledge |
560 | 1110 rcall WaitMSSP |
582 | 1111 |
560 | 1112 ; last byte in read from RX circuity always with a NACK! |
604 | 1113 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1114 rcall WaitMSSP |
1115 movff SSP1BUF,rx_firmware+1 | |
582 | 1116 bsf SSP1CON2,ACKDT |
1117 bsf SSP1CON2,ACKEN ; Master NOT acknowledge | |
560 | 1118 rcall WaitMSSP |
582 | 1119 bcf SSP1CON2,ACKDT ; Reset ACKDT flag |
1120 bsf SSP1CON2,PEN ; Stop condition | |
604 | 1121 rcall WaitMSSP |
1122 | |
1123 ; test for RX part not being ready during this read | |
1124 movff rx_firmware+1,i2c_temp1 | |
1125 movlw .147 | |
1126 cpfseq i2c_temp1 | |
1127 bra I2C_probe_OSTC_rx_2 ; not equal | |
1128 movff rx_firmware+0,i2c_temp1 | |
1129 movlw .27 | |
1130 cpfseq i2c_temp1 | |
1131 bra I2C_probe_OSTC_rx_2 ; not equal | |
1132 bsf active_reset_ostc_rx | |
1133 WAITMS .5 | |
1134 bcf active_reset_ostc_rx | |
1135 WAITMS .250 | |
1136 WAITMS .250 | |
1137 clrf i2c_temp1 | |
1138 decfsz lo_temp,F ; try max. 5 times | |
1139 bra I2C_probe_OSTC_rx_1 | |
1140 bcf ostc_rx_present ; Clear flag. Something is wrong | |
1141 I2C_probe_OSTC_rx_2: | |
1142 clrf i2c_temp1 | |
1143 return | |
582 | 1144 |
560 | 1145 |
1146 global I2C_get_tankdata | |
1147 I2C_get_tankdata: | |
582 | 1148 bsf SSP1CON2,SEN ; Start condition |
560 | 1149 rcall WaitMSSP |
582 | 1150 movlw 0x50 ; Address byte + Write bit |
1151 movwf SSP1BUF ; control byte | |
560 | 1152 rcall WaitMSSP |
1153 rcall I2C_WaitforACK | |
582 | 1154 movlw 0x1E ; Read buffer2 (48 Bytes) |
560 | 1155 movwf SSP1BUF ; Data Byte |
1156 rcall WaitMSSP | |
1157 rcall I2C_WaitforACK | |
582 | 1158 bsf SSP1CON2,PEN ; Stop condition |
560 | 1159 rcall WaitMSSP |
1160 WAITMS .1 | |
1161 | |
1162 ; read 48 bytes | |
582 | 1163 bsf SSP1CON2,SEN ; Start condition |
560 | 1164 rcall WaitMSSP |
582 | 1165 movlw 0x51 ; Address byte + read bit |
1166 movwf SSP1BUF ; control byte | |
560 | 1167 rcall WaitMSSP |
1168 rcall I2C_WaitforACK | |
582 | 1169 movlw .47 ; 47 with ACK + 1 w/o ACK |
1170 movwf i2c_temp2 | |
560 | 1171 lfsr FSR2,rx_buffer+0 |
1172 I2C_get_tankdata_loop_read: | |
582 | 1173 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1174 rcall WaitMSSP |
1175 movff SSP1BUF,POSTINC2 | |
582 | 1176 bcf SSP1CON2,ACKDT |
1177 bsf SSP1CON2,ACKEN ; Master acknowledge | |
560 | 1178 rcall WaitMSSP |
582 | 1179 decfsz i2c_temp2,F |
1180 bra I2C_get_tankdata_loop_read | |
560 | 1181 |
1182 ; 1 w/o ACK | |
582 | 1183 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1184 rcall WaitMSSP |
1185 movff SSP1BUF,POSTINC2 | |
582 | 1186 bsf SSP1CON2,ACKDT |
1187 bsf SSP1CON2,ACKEN ; Master NOT acknowledge | |
560 | 1188 rcall WaitMSSP |
582 | 1189 bcf SSP1CON2,ACKDT ; Reset ACKDT flag |
1190 | |
1191 bsf SSP1CON2,PEN ; Stop condition | |
1192 bra WaitMSSP ;(and return) | |
1193 | |
1194 | |
560 | 1195 global I2C_update_OSTC_rx |
582 | 1196 I2C_update_OSTC_rx: ; 992*64byte master loop |
1197 bcf i2c_error_flag ; clear error flag | |
560 | 1198 ; write 64 bytes |
582 | 1199 bsf SSP1CON2,SEN ; Start condition |
560 | 1200 rcall WaitMSSP |
582 | 1201 movlw 0x50 ; Address byte + Write bit |
1202 movwf SSP1BUF ; control byte | |
560 | 1203 rcall WaitMSSP |
1204 rcall I2C_WaitforACK | |
582 | 1205 lfsr FSR2,buffer ; send buffer for verify |
560 | 1206 movlw .64 |
582 | 1207 movwf i2c_temp2 |
1208 I2C_update_OSTC_loop: ; 64byte flash page loop | |
1209 movff up,POSTINC2 ; store for verify | |
560 | 1210 movff up,SSP1BUF |
1211 rcall WaitMSSP | |
1212 rcall I2C_WaitforACK | |
1213 call ext_flash_read_block ; Read one byte | |
582 | 1214 movwf up ; prepare for transmit |
1215 decfsz i2c_temp2,F | |
1216 bra I2C_update_OSTC_loop | |
1217 bsf SSP1CON2,PEN ; Stop condition | |
560 | 1218 rcall WaitMSSP |
1219 WAITMS .1 | |
1220 | |
1221 ; read 64 bytes | |
582 | 1222 bsf SSP1CON2,SEN ; Start condition |
560 | 1223 rcall WaitMSSP |
582 | 1224 movlw 0x51 ; Address byte + read bit |
1225 movwf SSP1BUF ; control byte | |
560 | 1226 rcall WaitMSSP |
1227 rcall I2C_WaitforACK | |
582 | 1228 lfsr FSR2,buffer ; send buffer for verify |
1229 movlw .63 ; 63 with ACK + 1 w/o ACK | |
1230 movwf i2c_temp2 | |
560 | 1231 I2C_update_OSTC_loop_read: |
582 | 1232 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1233 rcall WaitMSSP |
1234 movf SSP1BUF,W | |
582 | 1235 cpfseq POSTINC2 ; compare read-back with original |
1236 bsf i2c_error_flag ; Not equal, set flag | |
1237 bcf SSP1CON2,ACKDT | |
1238 bsf SSP1CON2,ACKEN ; Master acknowledge | |
560 | 1239 rcall WaitMSSP |
582 | 1240 decfsz i2c_temp2,F |
1241 bra I2C_update_OSTC_loop_read | |
560 | 1242 |
1243 ; 1 w/o ACK | |
582 | 1244 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1245 rcall WaitMSSP |
1246 movf SSP1BUF,W | |
582 | 1247 cpfseq POSTINC2 ; compare read-back with original |
1248 bsf i2c_error_flag ; Not equal, set flag | |
1249 bsf SSP1CON2,ACKDT | |
1250 bsf SSP1CON2,ACKEN ; Master NOT acknowledge | |
560 | 1251 rcall WaitMSSP |
582 | 1252 bcf SSP1CON2,ACKDT ; Reset ACKDT flag |
1253 | |
1254 bsf SSP1CON2,PEN ; Stop condition | |
560 | 1255 rcall WaitMSSP |
1256 WAITMS .1 | |
582 | 1257 |
1258 bsf SSP1CON2,SEN ; Start condition | |
560 | 1259 rcall WaitMSSP |
582 | 1260 movlw 0x50 ; Address byte + Write bit |
1261 movwf SSP1BUF ; control byte | |
560 | 1262 rcall WaitMSSP |
1263 rcall I2C_WaitforACK | |
582 | 1264 movlw 0x1F ; Write command! |
1265 movwf SSP1BUF ; Data Byte | |
560 | 1266 rcall WaitMSSP |
1267 rcall I2C_WaitforACK | |
582 | 1268 bsf SSP1CON2,PEN ; Stop condition |
560 | 1269 rcall WaitMSSP |
582 | 1270 WAITMS .5 ; Required waiting time |
1271 | |
560 | 1272 btfss i2c_error_flag |
582 | 1273 retlw .0 ; All ok |
1274 retlw .255 ; an error occurred | |
1275 | |
604 | 1276 ENDIF |
1277 | |
582 | 1278 END |