Mercurial > public > hwos_code
annotate src/i2c.asm @ 608:d866684249bd
work on 2.99 stable
author | heinrichsweikamp |
---|---|
date | Mon, 07 Jan 2019 21:13:43 +0100 |
parents | ca4556fb60b9 |
children | b87f23fae743 |
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 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 | |
604 | 72 I2CReset: ; something went wrong (slave holds SDA low?) |
582 | 73 clrf SSP1CON1 ; wake-up slave and reset entire module |
74 clrf SSP1CON2 | |
75 clrf SSP1STAT | |
76 bcf TRISC,3 ; SCL OUTPUT | |
604 | 77 bsf TRISC,4 ; SDA input |
582 | 78 bcf PORTC,3 |
79 movlw d'9' | |
80 movwf i2c_temp1 ; clock-out 9 clock cycles manually | |
0 | 81 I2CReset_1: |
604 | 82 bsf PORTC,3 ; SCL = 1 |
0 | 83 nop |
84 nop | |
85 nop | |
86 nop | |
604 | 87 btfsc PORTC,4 ; SDA = 1 ? |
88 bra I2CReset_2 ; YES - =1, SDA has been released from slave | |
89 bcf PORTC,3 ; NO - set 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 |
604 | 99 clrf SSP1CON1 ; setup I²C mode |
100 WAITMS d'10' ; reset-timeout for I2C devices | |
582 | 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 | |
604 | 114 bra I2C_WaitforACK ; returns... |
0 | 115 |
604 | 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 | |
582 | 121 I2C_TwoBytesRX_div16_2: ; divide lo:hi/16 (signed) only |
122 bcf STATUS,C | |
604 | 123 btfsc hi,7 ; copy sign bit to carry |
582 | 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 | |
604 | 129 btfsc hi,7 ; copy sign bit to carry |
582 | 130 bsf STATUS,C |
131 rrcf hi ; /4 | |
132 rrcf lo | |
133 bcf STATUS,C | |
604 | 134 btfsc hi,7 ; copy sign bit to carry |
582 | 135 bsf STATUS,C |
136 rrcf hi ; /8 | |
137 rrcf lo | |
138 bcf STATUS,C | |
604 | 139 btfsc hi,7 ; copy sign bit to carry |
582 | 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: |
604 | 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: |
604 | 152 bsf SSP1CON2,SEN ; start condition |
582 | 153 rcall WaitMSSP |
154 movlw 0x38 ; address | |
155 rcall I2C_TX | |
156 movlw 0x00 | |
157 rcall I2C_TX | |
604 | 158 bsf SSP1CON2,RSEN ; repeated start condition |
582 | 159 rcall WaitMSSP |
160 movlw 0x39 ; address | |
161 rcall I2C_TX | |
0 | 162 |
604 | 163 rcall I2C_OneByteRX ; get status byte |
582 | 164 movf SSP1BUF,W |
158 | 165 |
582 | 166 ; Non-flipped screen: |
167 ; Chip orientation on the PCB requires | |
604 | 168 ; Original = corrected |
582 | 169 ; x = -x |
170 ; y = -y | |
171 ; z = -z | |
0 | 172 |
582 | 173 ; Flipped screen: |
174 ; Chip orientation on the PCB requires | |
604 | 175 ; Original = corrected |
582 | 176 ; x = x |
177 ; y = y | |
178 ; z = -z | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
179 |
604 | 180 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
582 | 181 btfsc flip_screen ; 180° rotation ? |
604 | 182 bra I2C_RX_accelerometer2 ; YES |
183 comf hi ; 16 bit sign change | |
582 | 184 negf lo |
604 | 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: |
608 | 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) 0x60 | |
634 rcall I2C_TX | |
635 movlw b'00000000' ; CFG_REG_B_M (Low-Pass Filter off) 0x61 (set pulse is released every 63 ODR) | |
636 rcall I2C_TX | |
637 movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62 | |
638 rcall I2C_TX | |
639 bsf SSP1CON2,PEN ; Stop condition | |
640 bra WaitMSSP ;(And return) | |
582 | 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: | |
608 | 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'00000011' ; CFG_REG_A_M (Idle mode) 0x60 | |
697 rcall I2C_TX | |
698 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) | |
699 rcall I2C_TX | |
700 movlw b'01010001' ; CFG_REG_C_M 0x62 | |
701 rcall I2C_TX | |
702 movlw b'00000000' ; INT_CTRL_REG_M 0x63 | |
703 rcall I2C_TX | |
582 | 704 |
608 | 705 bsf SSP1CON2,PEN ; Stop condition |
706 bra WaitMSSP ; (And return) | |
707 | |
560 | 708 I2C_sleep_accelerometer2: |
608 | 709 ; accelerometer |
710 bsf SSP1CON2,SEN ; Start condition | |
711 rcall WaitMSSP | |
712 movlw 0x32 ; address | |
713 rcall I2C_TX | |
714 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
715 rcall I2C_TX | |
716 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) 0x1F | |
717 rcall I2C_TX | |
718 movlw b'00000000' ; CTRL_REG1_A (All off) 0x20 | |
719 rcall I2C_TX | |
720 bsf SSP1CON2,PEN ; Stop condition | |
721 bra WaitMSSP ; (And return) | |
0 | 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 |
895 ; global lt2942_get_temperature | |
582 | 896 ;lt2942_get_temperature: ; Read temperature registers |
897 ; clrf i2c_temp1 | |
898 ; movlw 0x0C ; Point to temperature registers | |
113 | 899 ; call I2C_TX_GAUGE |
900 ; call I2C_RX | |
582 | 901 ; bsf SSP1CON2,ACKEN ; Master acknowledge |
113 | 902 ; rcall WaitMSSP |
903 ; movff SSP1BUF,xA+1 | |
582 | 904 ; bsf SSP1CON2, RCEN ; Enable receive mode |
113 | 905 ; rcall WaitMSSP |
906 ; movff SSP1BUF,xA+0 | |
582 | 907 ; bsf SSP1CON2,PEN ; Stop condition |
113 | 908 ; rcall WaitMSSP |
909 ; | |
910 ;; banksel common | |
582 | 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 | |
113 | 917 ; |
582 | 918 ; ; devide xC (32bit)/65535 for result in 0.1K (16bit) |
919 ; movlw .16 | |
920 ; movwf i2c_temp1 | |
113 | 921 ;lt2942_get_temperature2: |
582 | 922 ; bcf STATUS,C |
923 ; rrcf xC+3,F | |
924 ; rrcf xC+2,F | |
925 ; rrcf xC+1,F | |
926 ; rrcf xC+0,F | |
927 ; decfsz i2c_temp1,F | |
928 ; bra lt2942_get_temperature2 | |
113 | 929 ; |
582 | 930 ; movff xC+1,sub_a+1 |
931 ; movff xC+0,sub_a+0 | |
932 ; movlw LOW .2731 ; Kelvin to Celsius offset | |
933 ; movwf sub_b+0 | |
934 ; movlw HIGH .2731 ; Kelvin to Celsius offset | |
935 ; movwf sub_b+1 | |
936 ; call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) | |
113 | 937 ; |
582 | 938 ; ; Update batttery_temperature in 0.1°C |
939 ; movff sub_c+1,battery_temperature+1 | |
940 ; movff sub_c+0,battery_temperature+0 | |
113 | 941 ; return |
942 | |
943 global lt2942_get_accumulated_charge | |
582 | 944 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent |
945 clrf i2c_temp1 | |
946 movlw 0x00 ; Point to status register | |
467 | 947 rcall I2C_TX_GAUGE |
948 rcall I2C_RX_GAUGE | |
582 | 949 bsf SSP1CON2,ACKEN ; Master acknowledge |
113 | 950 rcall WaitMSSP |
466 | 951 movff SSP1BUF,gauge_status_byte |
952 | |
582 | 953 bsf SSP1CON2, RCEN ; Enable receive mode |
954 rcall WaitMSSP ; Dummy read (Control byte) | |
467 | 955 movf SSP1BUF,W |
582 | 956 bsf SSP1CON2,ACKEN ; Master acknowledge |
467 | 957 rcall WaitMSSP |
582 | 958 |
959 bsf SSP1CON2, RCEN ; Enable receive mode | |
113 | 960 rcall WaitMSSP |
466 | 961 movff SSP1BUF,sub_a+1 |
582 | 962 bsf SSP1CON2,ACKEN ; Master acknowledge |
467 | 963 rcall WaitMSSP |
582 | 964 |
965 bsf SSP1CON2, RCEN ; Enable receive mode | |
466 | 966 rcall WaitMSSP |
967 movff SSP1BUF,sub_a+0 | |
582 | 968 bsf SSP1CON2,PEN ; Stop condition |
113 | 969 rcall WaitMSSP |
582 | 970 |
971 movff gauge_status_byte,sub_b+0 ; copy into bank common | |
972 btfsc sub_b+0,0 ; =1: UVLO Event | |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
973 rcall lt2942_init_again |
113 | 974 |
582 | 975 movff sub_a+1,battery_acumulated_charge+1 ; Save raw value |
976 movff sub_a+0,battery_acumulated_charge+0 ; Save raw value | |
977 | |
978 ; Compute batt_percent | |
979 ; (charge-battery_offset)/365 | |
980 movff battery_offset+0,sub_b+0 | |
981 movff battery_offset+1,sub_b+1 | |
982 call subU16 ; sub_c = sub_a - sub_b (with signed values) | |
113 | 983 |
582 | 984 clrf batt_percent ; Set to zero |
985 btfsc neg_flag ; result negative? | |
986 bra lt2942_set_to_zero_percent ; Yes, keep LT2942 at zero percent and return | |
113 | 987 |
582 | 988 ; > Zero, set batt_percent properly |
989 movff sub_c+0,xA+0 | |
990 movff sub_c+1,xA+1 | |
991 movff battery_capacity+0,xB+0 | |
992 movff battery_capacity+1,xB+1 | |
604 | 993 call div16x16 ; xC = xA / xB with xA as remainder |
582 | 994 movff xC+0,batt_percent |
995 return | |
113 | 996 |
449 | 997 lt2942_set_to_zero_percent: |
582 | 998 clrf i2c_temp1 |
999 movlw 0x02 ; Point to accumulated charge registers | |
449 | 1000 rcall I2C_TX_GAUGE |
1001 movff battery_offset+1,SSP1BUF | |
1002 rcall WaitMSSP | |
1003 rcall I2C_WaitforACK | |
1004 movff battery_offset+0,SSP1BUF | |
1005 rcall WaitMSSP | |
1006 rcall I2C_WaitforACK | |
582 | 1007 bsf SSP1CON2,PEN ; Stop condition |
1008 bra WaitMSSP ; (and return) | |
449 | 1009 |
113 | 1010 global lt2942_charge_done |
582 | 1011 lt2942_charge_done: ; Reset accumulating registers to 0xFFFF |
1012 clrf i2c_temp1 | |
1013 movlw 0x02 ; Point to accumulated charge registers | |
448 | 1014 rcall I2C_TX_GAUGE |
582 | 1015 setf SSP1BUF ; Data Byte |
113 | 1016 rcall WaitMSSP |
1017 rcall I2C_WaitforACK | |
582 | 1018 setf SSP1BUF ; Data Byte |
113 | 1019 rcall WaitMSSP |
1020 rcall I2C_WaitforACK | |
582 | 1021 bsf SSP1CON2,PEN ; Stop condition |
1022 bra WaitMSSP ; (and return) | |
113 | 1023 |
582 | 1024 I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC |
1025 movwf i2c_temp2 ; Data byte | |
1026 bsf SSP1CON2,SEN ; Start condition | |
113 | 1027 rcall WaitMSSP |
582 | 1028 movlw b'11001000' ; Address byte + Write bit |
1029 movwf SSP1BUF ; control byte | |
113 | 1030 rcall WaitMSSP |
1031 rcall I2C_WaitforACK | |
582 | 1032 movf i2c_temp2,W |
1033 bra I2C_TX ; (and return) | |
1034 | |
113 | 1035 I2C_RX_GAUGE: |
582 | 1036 bsf SSP1CON2,SEN ; Start condition |
113 | 1037 rcall WaitMSSP |
582 | 1038 movlw b'11001001' ; Address byte + Read bit |
1039 movwf SSP1BUF ; control byte | |
113 | 1040 rcall WaitMSSP |
1041 rcall I2C_WaitforACK | |
582 | 1042 bsf SSP1CON2, RCEN ; Enable receive mode |
1043 bra WaitMSSP ; (and return) | |
1044 | |
1045 | |
604 | 1046 ;----------------------------------------------------------------------------- |
1047 ; Transmitter Functions | |
1048 | |
1049 IFDEF _rx_functions | |
1050 | |
560 | 1051 global I2C_probe_OSTC_rx |
1052 I2C_probe_OSTC_rx: | |
604 | 1053 movlw .5 |
1054 movwf lo_temp | |
1055 I2C_probe_OSTC_rx_1: | |
582 | 1056 bsf SSP1CON2,SEN ; Start condition |
560 | 1057 rcall WaitMSSP |
582 | 1058 movlw 0x50 ; Address byte + Write bit |
1059 movwf SSP1BUF ; control byte | |
560 | 1060 rcall WaitMSSP |
582 | 1061 btfss SSP1CON2,ACKSTAT ; ACK? |
604 | 1062 bsf ostc_rx_present ; ACK sent - OSTC_RX present! |
582 | 1063 bsf SSP1CON2,PEN ; Stop condition |
560 | 1064 rcall WaitMSSP |
582 | 1065 btfss ostc_rx_present ; Do we have the RX? |
1066 return ; No, Done. | |
560 | 1067 WAITMS .1 |
582 | 1068 bsf SSP1CON2,SEN ; Start condition |
560 | 1069 rcall WaitMSSP |
582 | 1070 movlw 0x50 ; Address byte + Write bit |
1071 movwf SSP1BUF ; control byte | |
560 | 1072 rcall WaitMSSP |
1073 rcall I2C_WaitforACK | |
1074 movlw 0x1B | |
582 | 1075 movwf SSP1BUF ; Data Byte (Get firmware) |
560 | 1076 rcall WaitMSSP |
1077 rcall I2C_WaitforACK | |
582 | 1078 bsf SSP1CON2,PEN ; Stop condition |
560 | 1079 rcall WaitMSSP |
1080 WAITMS .1 | |
582 | 1081 bsf SSP1CON2,SEN ; Start condition |
560 | 1082 rcall WaitMSSP |
582 | 1083 movlw 0x51 ; Address byte + Read bit |
1084 movwf SSP1BUF ; control byte | |
560 | 1085 rcall WaitMSSP |
582 | 1086 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1087 rcall WaitMSSP |
1088 movff SSP1BUF,rx_firmware+0 | |
582 | 1089 bsf SSP1CON2,ACKEN ; Master acknowledge |
560 | 1090 rcall WaitMSSP |
582 | 1091 |
560 | 1092 ; last byte in read from RX circuity always with a NACK! |
604 | 1093 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1094 rcall WaitMSSP |
1095 movff SSP1BUF,rx_firmware+1 | |
582 | 1096 bsf SSP1CON2,ACKDT |
1097 bsf SSP1CON2,ACKEN ; Master NOT acknowledge | |
560 | 1098 rcall WaitMSSP |
582 | 1099 bcf SSP1CON2,ACKDT ; Reset ACKDT flag |
1100 bsf SSP1CON2,PEN ; Stop condition | |
604 | 1101 rcall WaitMSSP |
1102 | |
1103 ; test for RX part not being ready during this read | |
1104 movff rx_firmware+1,i2c_temp1 | |
1105 movlw .147 | |
1106 cpfseq i2c_temp1 | |
1107 bra I2C_probe_OSTC_rx_2 ; not equal | |
1108 movff rx_firmware+0,i2c_temp1 | |
1109 movlw .27 | |
1110 cpfseq i2c_temp1 | |
1111 bra I2C_probe_OSTC_rx_2 ; not equal | |
1112 bsf active_reset_ostc_rx | |
1113 WAITMS .5 | |
1114 bcf active_reset_ostc_rx | |
1115 WAITMS .250 | |
1116 WAITMS .250 | |
1117 clrf i2c_temp1 | |
1118 decfsz lo_temp,F ; try max. 5 times | |
1119 bra I2C_probe_OSTC_rx_1 | |
1120 bcf ostc_rx_present ; Clear flag. Something is wrong | |
1121 I2C_probe_OSTC_rx_2: | |
1122 clrf i2c_temp1 | |
1123 return | |
582 | 1124 |
560 | 1125 |
1126 global I2C_get_tankdata | |
1127 I2C_get_tankdata: | |
582 | 1128 bsf SSP1CON2,SEN ; Start condition |
560 | 1129 rcall WaitMSSP |
582 | 1130 movlw 0x50 ; Address byte + Write bit |
1131 movwf SSP1BUF ; control byte | |
560 | 1132 rcall WaitMSSP |
1133 rcall I2C_WaitforACK | |
582 | 1134 movlw 0x1E ; Read buffer2 (48 Bytes) |
560 | 1135 movwf SSP1BUF ; Data Byte |
1136 rcall WaitMSSP | |
1137 rcall I2C_WaitforACK | |
582 | 1138 bsf SSP1CON2,PEN ; Stop condition |
560 | 1139 rcall WaitMSSP |
1140 WAITMS .1 | |
1141 | |
1142 ; read 48 bytes | |
582 | 1143 bsf SSP1CON2,SEN ; Start condition |
560 | 1144 rcall WaitMSSP |
582 | 1145 movlw 0x51 ; Address byte + read bit |
1146 movwf SSP1BUF ; control byte | |
560 | 1147 rcall WaitMSSP |
1148 rcall I2C_WaitforACK | |
582 | 1149 movlw .47 ; 47 with ACK + 1 w/o ACK |
1150 movwf i2c_temp2 | |
560 | 1151 lfsr FSR2,rx_buffer+0 |
1152 I2C_get_tankdata_loop_read: | |
582 | 1153 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1154 rcall WaitMSSP |
1155 movff SSP1BUF,POSTINC2 | |
582 | 1156 bcf SSP1CON2,ACKDT |
1157 bsf SSP1CON2,ACKEN ; Master acknowledge | |
560 | 1158 rcall WaitMSSP |
582 | 1159 decfsz i2c_temp2,F |
1160 bra I2C_get_tankdata_loop_read | |
560 | 1161 |
1162 ; 1 w/o ACK | |
582 | 1163 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1164 rcall WaitMSSP |
1165 movff SSP1BUF,POSTINC2 | |
582 | 1166 bsf SSP1CON2,ACKDT |
1167 bsf SSP1CON2,ACKEN ; Master NOT acknowledge | |
560 | 1168 rcall WaitMSSP |
582 | 1169 bcf SSP1CON2,ACKDT ; Reset ACKDT flag |
1170 | |
1171 bsf SSP1CON2,PEN ; Stop condition | |
1172 bra WaitMSSP ;(and return) | |
1173 | |
1174 | |
560 | 1175 global I2C_update_OSTC_rx |
582 | 1176 I2C_update_OSTC_rx: ; 992*64byte master loop |
1177 bcf i2c_error_flag ; clear error flag | |
560 | 1178 ; write 64 bytes |
582 | 1179 bsf SSP1CON2,SEN ; Start condition |
560 | 1180 rcall WaitMSSP |
582 | 1181 movlw 0x50 ; Address byte + Write bit |
1182 movwf SSP1BUF ; control byte | |
560 | 1183 rcall WaitMSSP |
1184 rcall I2C_WaitforACK | |
582 | 1185 lfsr FSR2,buffer ; send buffer for verify |
560 | 1186 movlw .64 |
582 | 1187 movwf i2c_temp2 |
1188 I2C_update_OSTC_loop: ; 64byte flash page loop | |
1189 movff up,POSTINC2 ; store for verify | |
560 | 1190 movff up,SSP1BUF |
1191 rcall WaitMSSP | |
1192 rcall I2C_WaitforACK | |
1193 call ext_flash_read_block ; Read one byte | |
582 | 1194 movwf up ; prepare for transmit |
1195 decfsz i2c_temp2,F | |
1196 bra I2C_update_OSTC_loop | |
1197 bsf SSP1CON2,PEN ; Stop condition | |
560 | 1198 rcall WaitMSSP |
1199 WAITMS .1 | |
1200 | |
1201 ; read 64 bytes | |
582 | 1202 bsf SSP1CON2,SEN ; Start condition |
560 | 1203 rcall WaitMSSP |
582 | 1204 movlw 0x51 ; Address byte + read bit |
1205 movwf SSP1BUF ; control byte | |
560 | 1206 rcall WaitMSSP |
1207 rcall I2C_WaitforACK | |
582 | 1208 lfsr FSR2,buffer ; send buffer for verify |
1209 movlw .63 ; 63 with ACK + 1 w/o ACK | |
1210 movwf i2c_temp2 | |
560 | 1211 I2C_update_OSTC_loop_read: |
582 | 1212 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1213 rcall WaitMSSP |
1214 movf SSP1BUF,W | |
582 | 1215 cpfseq POSTINC2 ; compare read-back with original |
1216 bsf i2c_error_flag ; Not equal, set flag | |
1217 bcf SSP1CON2,ACKDT | |
1218 bsf SSP1CON2,ACKEN ; Master acknowledge | |
560 | 1219 rcall WaitMSSP |
582 | 1220 decfsz i2c_temp2,F |
1221 bra I2C_update_OSTC_loop_read | |
560 | 1222 |
1223 ; 1 w/o ACK | |
582 | 1224 bsf SSP1CON2, RCEN ; Enable receive mode |
560 | 1225 rcall WaitMSSP |
1226 movf SSP1BUF,W | |
582 | 1227 cpfseq POSTINC2 ; compare read-back with original |
1228 bsf i2c_error_flag ; Not equal, set flag | |
1229 bsf SSP1CON2,ACKDT | |
1230 bsf SSP1CON2,ACKEN ; Master NOT acknowledge | |
560 | 1231 rcall WaitMSSP |
582 | 1232 bcf SSP1CON2,ACKDT ; Reset ACKDT flag |
1233 | |
1234 bsf SSP1CON2,PEN ; Stop condition | |
560 | 1235 rcall WaitMSSP |
1236 WAITMS .1 | |
582 | 1237 |
1238 bsf SSP1CON2,SEN ; Start condition | |
560 | 1239 rcall WaitMSSP |
582 | 1240 movlw 0x50 ; Address byte + Write bit |
1241 movwf SSP1BUF ; control byte | |
560 | 1242 rcall WaitMSSP |
1243 rcall I2C_WaitforACK | |
582 | 1244 movlw 0x1F ; Write command! |
1245 movwf SSP1BUF ; Data Byte | |
560 | 1246 rcall WaitMSSP |
1247 rcall I2C_WaitforACK | |
582 | 1248 bsf SSP1CON2,PEN ; Stop condition |
560 | 1249 rcall WaitMSSP |
582 | 1250 WAITMS .5 ; Required waiting time |
1251 | |
560 | 1252 btfss i2c_error_flag |
582 | 1253 retlw .0 ; All ok |
1254 retlw .255 ; an error occurred | |
1255 | |
604 | 1256 ENDIF |
1257 | |
582 | 1258 END |