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