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