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