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