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