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