comparison src/i2c.asm @ 615:b87f23fae743

work on new battery menu
author heinrichsweikamp
date Sat, 02 Feb 2019 17:39:44 +0100
parents d866684249bd
children 935e20e16dff
comparison
equal deleted inserted replaced
614:a32212cd5ea9 615:b87f23fae743
45 45
46 46
47 i2c CODE 47 i2c CODE
48 48
49 ;============================================================================= 49 ;=============================================================================
50
51 I2C_TX:
52 movwf SSP1BUF
53 rcall WaitMSSP
54 bra I2C_WaitforACK ; returns...
55
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
61 I2C_TwoBytesRX_div16_2: ; divide lo:hi/16 (signed) only
62 bcf STATUS,C
63 btfsc hi,7 ; copy sign bit to carry
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
69 btfsc hi,7 ; copy sign bit to carry
70 bsf STATUS,C
71 rrcf hi ; /4
72 rrcf lo
73 bcf STATUS,C
74 btfsc hi,7 ; copy sign bit to carry
75 bsf STATUS,C
76 rrcf hi ; /8
77 rrcf lo
78 bcf STATUS,C
79 btfsc hi,7 ; copy sign bit to carry
80 bsf STATUS,C
81 rrcf hi ; /16
82 rrcf lo
83 return
84
85 global I2C_RX_accelerometer
86 I2C_RX_accelerometer:
87 btfsc compass_type2 ; compass2 ?
88 bra I2C_RX_accelerometer_compass2 ; YES
89 btfsc compass_type ; compass1 ?
90 bra I2C_RX_accelerometer_compass1 ; YES
91 I2C_RX_accelerometer_compass0:
92 bsf SSP1CON2,SEN ; start condition
93 rcall WaitMSSP
94 movlw 0x38 ; address
95 rcall I2C_TX
96 movlw 0x00
97 rcall I2C_TX
98 bsf SSP1CON2,RSEN ; repeated start condition
99 rcall WaitMSSP
100 movlw 0x39 ; address
101 rcall I2C_TX
102
103 rcall I2C_OneByteRX ; get status byte
104 movf SSP1BUF,W
105
106 ; Non-flipped screen:
107 ; Chip orientation on the PCB requires
108 ; Original = corrected
109 ; x = -x
110 ; y = -y
111 ; z = -z
112
113 ; Flipped screen:
114 ; Chip orientation on the PCB requires
115 ; Original = corrected
116 ; x = x
117 ; y = y
118 ; z = -z
119
120 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed)
121 btfsc flip_screen ; 180° rotation ?
122 bra I2C_RX_accelerometer2 ; YES
123 comf hi ; 16 bit sign change
124 negf lo
125 btfsc STATUS,C ; carry to propagate ?
126 incf hi,F ; YES - do it
127 I2C_RX_accelerometer2:
128 movff lo,accel_DX+0
129 movff hi,accel_DX+1 ; Copy result
130
131 rcall I2C_TwoBytesRX_div16 ; Get two bytes and divide /16 (signed)
132 btfsc flip_screen ; 180° rotation ?
133 bra I2C_RX_accelerometer3 ; Yes
134 comf hi ; 16bit sign change.
135 negf lo
136 btfsc STATUS,C ; Carry to propagate ?
137 incf hi,F ; YES: do it.
138 I2C_RX_accelerometer3:
139 movff lo,accel_DY+0
140 movff hi,accel_DY+1 ; Copy result
141
142 rcall I2C_OneByteRX ; Get one byte
143 movff SSP1BUF,hi ; Data Byte
144 bsf SSP1CON2, RCEN ; Enable receive mode
145 rcall WaitMSSP
146 ; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+0)...
147 movff SSP1BUF,lo ; Data Byte
148
149 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
150 comf hi ; 16bit sign change.
151 negf lo
152 btfsc STATUS,C ; Carry to propagate ?
153 incf hi,F ; YES: do it.
154 movff lo,accel_DZ+0
155 movff hi,accel_DZ+1 ; Copy result
156
157 bsf SSP1CON2,PEN ; Stop condition
158 bra WaitMSSP ; (And return)
159
160 I2C_RX_accelerometer_compass1:
161 bsf SSP1CON2,SEN ; Start condition
162 rcall WaitMSSP
163 movlw 0x3C ; address
164 rcall I2C_TX
165 movlw b'10101000' ; 0x28 with auto-increment (MSB=1)
166 rcall I2C_TX
167 bsf SSP1CON2,RSEN ; Repeated start condition (!)
168 rcall WaitMSSP
169 movlw 0x3D ; address
170 I2C_RX_accelerometer_compass1_xx: ; compass2 continues here...
171 rcall I2C_TX
172
173 ; Non-flipped screen:
174 ; Chip orientation on the PCB requires
175 ; Original = Corrected
176 ; x = -x (Compass 1)
177 ; x = x (Compass 2)
178 ; y = -y
179 ; z = -z
180
181 ; Flipped screen:
182 ; Chip orientation on the PCB requires
183 ; Original = Corrected
184 ; x = x (Compass 1)
185 ; x = -x (Compass 2)
186 ; y = y
187 ; z = -z
188
189 ; Dump the accelerator data
190 rcall I2C_OneByteRX
191 movff SSP1BUF,lo ; accel_DX+0
192 rcall I2C_OneByteRX
193 movff SSP1BUF,hi ;accel_DX+1
194 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
195 btfss compass_type2 ; compass 2?
196 bra I2C_RX_accelerometer1_c1 ; No, compass 1
197 ; compass 2
198 btfss flip_screen ; 180° rotation ?
199 bra I2C_RX_accelerometer2_c1 ; No, continue with normal compass1 routines for Y and Z
200 ; flipped compass 2, negate x
201 comf hi ; 16bit sign change.
202 negf lo
203 btfsc STATUS,C ; Carry to propagate ?
204 incf hi,F ; YES: do it.
205 bra I2C_RX_accelerometer2_c1 ; continue with normal compass1 routines for Y and Z
206
207 I2C_RX_accelerometer1_c1:
208 btfsc flip_screen ; 180° rotation ?
209 bra I2C_RX_accelerometer2_c1 ; Yes
210 ; non-flipped compass 1, negate x
211 comf hi ; 16bit sign change.
212 negf lo
213 btfsc STATUS,C ; Carry to propagate ?
214 incf hi,F ; YES: do it.
215 I2C_RX_accelerometer2_c1:
216 ; flipped compass 1, non-flipped compass 2
217 movff lo,accel_DX+0
218 movff hi,accel_DX+1 ; Copy result
219 rcall I2C_OneByteRX
220 movff SSP1BUF,lo ; accel_DY+0
221 rcall I2C_OneByteRX
222 movff SSP1BUF,hi ; accel_DY+1
223
224 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
225 btfsc flip_screen ; 180° rotation ?
226 bra I2C_RX_accelerometer3_c1 ; Yes
227 comf hi ; 16bit sign change.
228 negf lo
229 btfsc STATUS,C ; Carry to propagate ?
230 incf hi,F ; YES: do it.
231 I2C_RX_accelerometer3_c1:
232 movff lo,accel_DY+0
233 movff hi,accel_DY+1 ; Copy result
234
235 rcall I2C_OneByteRX
236 movff SSP1BUF,lo ;accel_DZ+0
237 bsf SSP1CON2, RCEN ; Enable receive mode
238 rcall WaitMSSP
239 ; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+1)...
240 movff SSP1BUF,hi ;accel_DZ+1
241 bsf SSP1CON2,PEN ; Stop condition
242 rcall WaitMSSP
243 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
244 comf hi ; 16bit sign change for Z
245 negf lo
246 btfsc STATUS,C ; Carry to propagate ?
247 incf hi,F ; YES: do it.
248 movff lo,accel_DZ+0
249 movff hi,accel_DZ+1 ; Copy result
250 return
251
252 I2C_RX_accelerometer_compass2:
253 bsf SSP1CON2,SEN ; Start condition
254 rcall WaitMSSP
255 movlw 0x32 ; address
256 rcall I2C_TX
257 movlw b'10101000' ; 0x28 with auto-increment (MSB=1)
258 rcall I2C_TX
259 bsf SSP1CON2,RSEN ; Repeated start condition (!)
260 rcall WaitMSSP
261 movlw 0x33 ; address
262 bra I2C_RX_accelerometer_compass1_xx
263
264 I2C_OneByteRX:
265 bsf SSP1CON2,RCEN ; Enable receive mode
266 rcall WaitMSSP
267 bsf SSP1CON2,ACKEN ; Master acknowledge
268 bra WaitMSSP ; And return!
269
270 global I2C_RX_compass
271 I2C_RX_compass:
272 btfsc compass_type2 ; compass2
273 bra I2C_RX_compass2 ; yes
274 btfsc compass_type ; compass1?
275 bra I2C_RX_compass1 ; yes
276 I2C_RX_compass0:
277 bsf SSP1CON2,SEN ; Start condition
278 rcall WaitMSSP
279 movlw 0x3C ; address
280 rcall I2C_TX
281 movlw 0x03
282 rcall I2C_TX
283 bsf SSP1CON2,PEN ; Stop condition
284 rcall WaitMSSP
285
286 bcf PIR1,SSP1IF
287 bsf SSP1CON2,SEN ; Start condition
288 rcall WaitMSSP
289 movlw 0x3D ; address
290 rcall I2C_TX
291
292 ; Compass IC sends data in following order:
293 ; x MSB
294 ; x LSB
295 ; z MSB
296 ; z LSB
297 ; y MSB
298 ; y LSB
299
300 ; Non-flipped screen
301 ; Chip orientation on the PCB requires
302 ; Original = Corrected
303 ; x = -y
304 ; z = z
305 ; y = x
306
307 ; Flipped screen
308 ; Chip orientation on the PCB requires
309 ; Original = Corrected
310 ; x = y
311 ; z = z
312 ; y = -x
313
314 rcall I2C_OneByteRX ; Get one byte
315 movff SSP1BUF,compass_DY+1 ; Data Byte
316 rcall I2C_OneByteRX ; Get one byte
317 movff SSP1BUF,compass_DY+0 ; Data Byte
318 btfsc flip_screen ; 180° rotation ?
319 bra I2C_RX_compass0_2 ; Yes
320 banksel compass_DY
321 comf compass_DY+1 ; 16bit sign change.
322 negf compass_DY+0
323 btfsc STATUS,C ; Carry to propagate ?
324 incf compass_DY+1,F ; YES: do it.
325 I2C_RX_compass0_2:
326 banksel common
327 rcall I2C_OneByteRX ; Get one byte
328 movff SSP1BUF,compass_DZ+1 ; Data Byte
329 rcall I2C_OneByteRX ; Get one byte
330 movff SSP1BUF,compass_DZ+0 ; Data Byte
331 rcall I2C_OneByteRX ; Get one byte
332 movff SSP1BUF,compass_DX+1 ; Data Byte
333 bsf SSP1CON2, RCEN ; Enable receive mode
334 rcall WaitMSSP
335 movff SSP1BUF,compass_DX+0 ; Data Byte
336 bsf SSP1CON2,PEN ; Stop condition
337 rcall WaitMSSP
338 btfss flip_screen ; 180° rotation ?
339 return ; No, done.
340 ; Yes, flip X
341 banksel compass_DX
342 comf compass_DX+1 ; 16bit sign change.
343 negf compass_DX+0
344 btfsc STATUS,C ; Carry to propagate ?
345 incf compass_DX+1,F ; YES: do it.
346 banksel common
347 return
348
349 I2C_RX_compass1: ; New compass
350 bsf SSP1CON2,SEN ; Start condition
351 rcall WaitMSSP
352 movlw 0x3C ; address
353 rcall I2C_TX
354 movlw b'10001000' ; 0x08 with auto-increment (MSB=1)
355 rcall I2C_TX
356 bsf SSP1CON2,RSEN ; Repeated start condition (!)
357 rcall WaitMSSP
358 movlw 0x3D ; address
359 rcall I2C_TX
360 ;rcall WaitMSSP ; Needed? (mH)
361 rcall I2C_OneByteRX ; Get one byte
362 movff SSP1BUF,lo ; Data Byte
363 rcall I2C_OneByteRX ; Get one byte
364 movff SSP1BUF,hi ; Data Byte
365 rcall I2C_TwoBytesRX_div8_2
366 movff lo,compass_DX+0
367 movff hi,compass_DX+1
368 btfss flip_screen ; 180° rotation ?
369 bra I2C_RX_compass1_1 ; Yes
370 ; Yes, flip X
371 banksel compass_DX
372 comf compass_DX+1 ; 16bit sign change.
373 negf compass_DX+0
374 btfsc STATUS,C ; Carry to propagate ?
375 incf compass_DX+1,F ; YES: do it.
376 banksel common
377 I2C_RX_compass1_1:
378 rcall I2C_OneByteRX ; Get one byte
379 movff SSP1BUF,lo ; Data Byte
380 rcall I2C_OneByteRX ; Get one byte
381 movff SSP1BUF,hi ; Data Byte
382 rcall I2C_TwoBytesRX_div8_2
383 movff lo,compass_DY+0
384 movff hi,compass_DY+1
385 btfss flip_screen ; 180° rotation ?
386 bra I2C_RX_compass1_2 ; Yes
387 ; Yes, flip Y
388 banksel compass_DY
389 comf compass_DY+1 ; 16bit sign change.
390 negf compass_DY+0
391 btfsc STATUS,C ; Carry to propagate ?
392 incf compass_DY+1,F ; YES: do it.
393 I2C_RX_compass1_2:
394 banksel common
395 rcall I2C_OneByteRX ; Get one byte
396 movff SSP1BUF,lo ; Data Byte
397 bsf SSP1CON2, RCEN ; Enable receive mode
398 rcall WaitMSSP
399 movff SSP1BUF,hi ; Data Byte
400 rcall I2C_TwoBytesRX_div8_2
401 movff lo,compass_DZ+0
402 movff hi,compass_DZ+1
403 bsf SSP1CON2,PEN ; Stop condition
404 bra WaitMSSP ;(And return)
405
406 I2C_RX_compass2: ; newest compass
407 bsf SSP1CON2,SEN ; Start condition
408 rcall WaitMSSP
409 movlw 0x3C ; address
410 rcall I2C_TX
411 movlw 0xE8 ; 0x68 with auto-increment (MSB=1)
412 rcall I2C_TX
413 bsf SSP1CON2,RSEN ; Repeated start condition (!)
414 rcall WaitMSSP
415 movlw 0x3D ; address
416 rcall I2C_TX
417 ; rcall WaitMSSP
418 rcall I2C_OneByteRX ; Get one byte
419 movff SSP1BUF,lo ; Data Byte
420 rcall I2C_OneByteRX ; Get one byte
421 movff SSP1BUF,hi ; Data Byte
422 ; rcall I2C_TwoBytesRX_div8_2
423 btfsc flip_screen ; 180° rotation ?
424 bra I2C_RX_compass2_1 ; Yes, do nothing with X
425 ; No, flip X
426 comf hi ; 16bit sign change.
427 negf lo
428 btfsc STATUS,C ; Carry to propagate ?
429 incf hi,F ; YES: do it.
430 I2C_RX_compass2_1:
431 movff lo,compass_DX+0
432 movff hi,compass_DX+1
433 rcall I2C_OneByteRX ; Get one byte
434 movff SSP1BUF,lo ; Data Byte
435 rcall I2C_OneByteRX ; Get one byte
436 movff SSP1BUF,hi ; Data Byte
437 ; rcall I2C_TwoBytesRX_div8_2
438 btfss flip_screen ; 180° rotation ?
439 bra I2C_RX_compass2_2 ; No, do nothing with Y
440 ; Yes, flip Y
441 comf hi ; 16bit sign change.
442 negf lo
443 btfsc STATUS,C ; Carry to propagate ?
444 incf hi,F ; YES: do it.
445 I2C_RX_compass2_2:
446 movff lo,compass_DY+0
447 movff hi,compass_DY+1
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
452 ; rcall I2C_TwoBytesRX_div8_2
453 movff lo,compass_DZ+0
454 movff hi,compass_DZ+1
455 bsf SSP1CON2,PEN ; Stop condition
456 bra WaitMSSP ;(And return)
457
458
459 global I2C_init_compass
460 I2C_init_compass:
461 bsf compass_enabled
462 bcf compass_type2
463 ; probe compass 2
464 bsf SSP1CON2,SEN ; Start condition
465 rcall WaitMSSP
466 movlw 0x32 ; Address byte + Write bit
467 movwf SSP1BUF ; control byte
468 rcall WaitMSSP
469 btfss SSP1CON2,ACKSTAT ; ACK?
470 bsf compass_type2 ; ACK send. compass2 present
471 bsf SSP1CON2,PEN ; Stop condition
472 rcall WaitMSSP
473
474 btfsc compass_type2
475 bra I2C_init_compass2 ; Compass2
476 ; Check for compass0 or compass1...
477 bsf compass_type ; set flag
478 bsf SSP1CON2,SEN ; Start condition
479 rcall WaitMSSP
480 movlw 0x3C ; address
481 rcall I2C_TX
482 movlw 0x0F
483 rcall I2C_TX
484 bsf SSP1CON2,PEN ; Stop condition
485 rcall WaitMSSP
486 bcf PIR1,SSP1IF
487 bsf SSP1CON2,SEN ; Start condition
488 rcall WaitMSSP
489 movlw 0x3D ; address
490 rcall I2C_TX
491 rcall I2C_OneByteRX ; Get one byte
492 movlw 0x49 ; 0x49 = Compass1
493 cpfseq SSP1BUF
494 bcf compass_type ; clear flag
495 bsf SSP1CON2,PEN ; Stop condition
496 rcall WaitMSSP
497
498 btfsc compass_type ; compass1?
499 bra I2C_init_compass1 ; yes
500 ; init compass0
501 bsf SSP1CON2,SEN ; Start condition
502 rcall WaitMSSP
503 movlw 0x3C ; address
504 rcall I2C_TX
505 movlw 0x00
506 rcall I2C_TX
507 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias)
508 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged
509 rcall I2C_TX
510 I2C_init_compass_common:
511 movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss)
512 swapf i2c_temp1,F
513 comf i2c_temp1,F
514 bcf STATUS,C
515 rlcf i2c_temp1
516 movf i2c_temp1,W
517 clrf i2c_temp1
518 rcall I2C_TX
519 movlw b'00000000' ; Continuous Mode
520 rcall I2C_TX
521 bsf SSP1CON2,PEN ; Stop condition
522 bra WaitMSSP ; (And return)
523
524 I2C_init_compass1:
525 bsf SSP1CON2,SEN ; Start condition
526 rcall WaitMSSP
527 movlw 0x3C ; address
528 rcall I2C_TX
529 movlw 0x9F ; 1F with auto-increment (MSB=1)
530 rcall I2C_TX
531 movlw b'00000000' ; CTRL0
532 rcall I2C_TX
533 movlw b'00101111' ; CTRL1 (6,25Hz, BDU=0, x,y,z = ON)
534 rcall I2C_TX
535 movlw b'11000000' ; CTRL2 (50Hz, +/-2g,
536 rcall I2C_TX
537 movlw b'00000000' ; CTRL3
538 rcall I2C_TX
539 movlw b'00000000' ; CTRL4
540 rcall I2C_TX
541 movlw b'01100100' ; CTRL5 HIGH res, 6,25Hz
542 rcall I2C_TX
543 init_compass1_common:
544 movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) +++
545 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
546 dcfsnz i2c_temp1,F ; = 1?
547 movlw b'01100000' ; Yes, CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
548 dcfsnz i2c_temp1,F ; = 2?
549 movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss)
550 dcfsnz i2c_temp1,F ; = 3?
551 movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss)
552 dcfsnz i2c_temp1,F ; = 4?
553 movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss)
554 dcfsnz i2c_temp1,F ; = 5?
555 movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss)
556 dcfsnz i2c_temp1,F ; = 6?
557 movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss)
558 dcfsnz i2c_temp1,F ; = 7?
559 movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss)
560 rcall I2C_TX
561 movlw b'00000000' ; CTRL7 Continuous Mode
562 rcall I2C_TX
563 bsf SSP1CON2,PEN ; Stop condition
564 bra WaitMSSP ; (And return)
565
566 I2C_init_compass2:
567 bsf SSP1CON2,SEN ; Start condition
568 rcall WaitMSSP
569 movlw 0x3C ; address
570 rcall I2C_TX
571 movlw 0xE0 ; 0x60 with auto-increment (MSB=1)
572 rcall I2C_TX
573 movlw b'00000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60
574 rcall I2C_TX
575 movlw b'00000000' ; CFG_REG_B_M (Low-Pass Filter off) 0x61 (set pulse is released every 63 ODR)
576 rcall I2C_TX
577 movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62
578 rcall I2C_TX
579 bsf SSP1CON2,PEN ; Stop condition
580 bra WaitMSSP ;(And return)
581
582
583 global I2C_sleep_compass
584 I2C_sleep_compass:
585 bcf compass_enabled
586 btfsc compass_type2 ; compass2?
587 bra I2C_sleep_compass2 ; yes
588 btfsc compass_type ; compass1?
589 bra I2C_sleep_compass1 ; yes
590 I2C_sleep_compass0:
591 bsf SSP1CON2,SEN ; Start condition
592 rcall WaitMSSP
593 movlw 0x3C ; address
594 rcall I2C_TX
595 movlw 0x00
596 rcall I2C_TX
597 movlw b'01101000' ; ConfigA
598 rcall I2C_TX
599 movlw b'00100000' ; ConfigB
600 rcall I2C_TX
601 movlw b'00000010' ; Idle Mode
602 rcall I2C_TX
603 bsf SSP1CON2,PEN ; Stop condition
604 bra WaitMSSP ; (And return)
605
606 I2C_sleep_compass1:
607 bsf SSP1CON2,SEN ; Start condition
608 rcall WaitMSSP
609 movlw 0x3C ; address
610 rcall I2C_TX
611 movlw 0x20 ; CTRL_REG1
612 rcall I2C_TX
613 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor Power-down mode
614 rcall I2C_TX
615 bsf SSP1CON2,PEN ; Stop condition
616 rcall WaitMSSP
617 bsf SSP1CON2,SEN ; Start condition
618 rcall WaitMSSP
619 movlw 0x3C ; address
620 rcall I2C_TX
621 movlw 0x26 ; CTRL_REG7
622 rcall I2C_TX
623 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor Power-down mode
624 rcall I2C_TX
625 bsf SSP1CON2,PEN ; Stop condition
626 bra WaitMSSP ;(And return)
627
628 I2C_sleep_compass2:
629 ; magnetic
630 bsf SSP1CON2,SEN ; Start condition
631 rcall WaitMSSP
632 movlw 0x3C ; address
633 rcall I2C_TX
634 movlw 0xE0 ; 0x60 with auto-increment (MSB=1)
635 rcall I2C_TX
636 movlw b'00000011' ; CFG_REG_A_M (Idle mode) 0x60
637 rcall I2C_TX
638 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition)
639 rcall I2C_TX
640 movlw b'01010001' ; CFG_REG_C_M 0x62
641 rcall I2C_TX
642 movlw b'00000000' ; INT_CTRL_REG_M 0x63
643 rcall I2C_TX
644
645 bsf SSP1CON2,PEN ; Stop condition
646 bra WaitMSSP ; (And return)
647
648 I2C_sleep_accelerometer2:
649 ; accelerometer
650 bsf SSP1CON2,SEN ; Start condition
651 rcall WaitMSSP
652 movlw 0x32 ; address
653 rcall I2C_TX
654 movlw 0x9F ; 1F with auto-increment (MSB=1)
655 rcall I2C_TX
656 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) 0x1F
657 rcall I2C_TX
658 movlw b'00000000' ; CTRL_REG1_A (All off) 0x20
659 rcall I2C_TX
660 bsf SSP1CON2,PEN ; Stop condition
661 bra WaitMSSP ; (And return)
50 662
51 WaitMSSP: 663 WaitMSSP:
52 decfsz i2c_temp1,F ; check for timeout during I2C action 664 decfsz i2c_temp1,F ; check for timeout during I2C action
53 bra WaitMSSP2 665 bra WaitMSSP2
54 bra I2CFail ; timeout occurred 666 bra I2CFail ; timeout occurred
105 movlw b'00000000' 717 movlw b'00000000'
106 movwf SSP1CON2 718 movwf SSP1CON2
107 movlw 0x27 719 movlw 0x27
108 movwf SSP1ADD 720 movwf SSP1ADD
109 return 721 return
110
111 I2C_TX:
112 movwf SSP1BUF
113 rcall WaitMSSP
114 bra I2C_WaitforACK ; returns...
115
116 I2C_TwoBytesRX_div16: ; get two bytes and divide lo:hi/16 (signed)
117 rcall I2C_OneByteRX ; get one byte
118 movff SSP1BUF,hi ; data byte
119 rcall I2C_OneByteRX ; get one byte
120 movff SSP1BUF,lo ; data byte
121 I2C_TwoBytesRX_div16_2: ; divide lo:hi/16 (signed) only
122 bcf STATUS,C
123 btfsc hi,7 ; copy sign bit to carry
124 bsf STATUS,C
125 rrcf hi ; /2
126 rrcf lo
127 I2C_TwoBytesRX_div8_2: ; divide lo:hi/8 (signed) only
128 bcf STATUS,C
129 btfsc hi,7 ; copy sign bit to carry
130 bsf STATUS,C
131 rrcf hi ; /4
132 rrcf lo
133 bcf STATUS,C
134 btfsc hi,7 ; copy sign bit to carry
135 bsf STATUS,C
136 rrcf hi ; /8
137 rrcf lo
138 bcf STATUS,C
139 btfsc hi,7 ; copy sign bit to carry
140 bsf STATUS,C
141 rrcf hi ; /16
142 rrcf lo
143 return
144
145 global I2C_RX_accelerometer
146 I2C_RX_accelerometer:
147 btfsc compass_type2 ; compass2 ?
148 bra I2C_RX_accelerometer_compass2 ; YES
149 btfsc compass_type ; compass1 ?
150 bra I2C_RX_accelerometer_compass1 ; YES
151 I2C_RX_accelerometer_compass0:
152 bsf SSP1CON2,SEN ; start condition
153 rcall WaitMSSP
154 movlw 0x38 ; address
155 rcall I2C_TX
156 movlw 0x00
157 rcall I2C_TX
158 bsf SSP1CON2,RSEN ; repeated start condition
159 rcall WaitMSSP
160 movlw 0x39 ; address
161 rcall I2C_TX
162
163 rcall I2C_OneByteRX ; get status byte
164 movf SSP1BUF,W
165
166 ; Non-flipped screen:
167 ; Chip orientation on the PCB requires
168 ; Original = corrected
169 ; x = -x
170 ; y = -y
171 ; z = -z
172
173 ; Flipped screen:
174 ; Chip orientation on the PCB requires
175 ; Original = corrected
176 ; x = x
177 ; y = y
178 ; z = -z
179
180 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed)
181 btfsc flip_screen ; 180° rotation ?
182 bra I2C_RX_accelerometer2 ; YES
183 comf hi ; 16 bit sign change
184 negf lo
185 btfsc STATUS,C ; carry to propagate ?
186 incf hi,F ; YES - do it
187 I2C_RX_accelerometer2:
188 movff lo,accel_DX+0
189 movff hi,accel_DX+1 ; Copy result
190
191 rcall I2C_TwoBytesRX_div16 ; Get two bytes and divide /16 (signed)
192 btfsc flip_screen ; 180° rotation ?
193 bra I2C_RX_accelerometer3 ; Yes
194 comf hi ; 16bit sign change.
195 negf lo
196 btfsc STATUS,C ; Carry to propagate ?
197 incf hi,F ; YES: do it.
198 I2C_RX_accelerometer3:
199 movff lo,accel_DY+0
200 movff hi,accel_DY+1 ; Copy result
201
202 rcall I2C_OneByteRX ; Get one byte
203 movff SSP1BUF,hi ; Data Byte
204 bsf SSP1CON2, RCEN ; Enable receive mode
205 rcall WaitMSSP
206 ; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+0)...
207 movff SSP1BUF,lo ; Data Byte
208
209 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
210 comf hi ; 16bit sign change.
211 negf lo
212 btfsc STATUS,C ; Carry to propagate ?
213 incf hi,F ; YES: do it.
214 movff lo,accel_DZ+0
215 movff hi,accel_DZ+1 ; Copy result
216
217 bsf SSP1CON2,PEN ; Stop condition
218 bra WaitMSSP ; (And return)
219
220 I2C_RX_accelerometer_compass1:
221 bsf SSP1CON2,SEN ; Start condition
222 rcall WaitMSSP
223 movlw 0x3C ; address
224 rcall I2C_TX
225 movlw b'10101000' ; 0x28 with auto-increment (MSB=1)
226 rcall I2C_TX
227 bsf SSP1CON2,RSEN ; Repeated start condition (!)
228 rcall WaitMSSP
229 movlw 0x3D ; address
230 I2C_RX_accelerometer_compass1_xx: ; compass2 continues here...
231 rcall I2C_TX
232
233 ; Non-flipped screen:
234 ; Chip orientation on the PCB requires
235 ; Original = Corrected
236 ; x = -x (Compass 1)
237 ; x = x (Compass 2)
238 ; y = -y
239 ; z = -z
240
241 ; Flipped screen:
242 ; Chip orientation on the PCB requires
243 ; Original = Corrected
244 ; x = x (Compass 1)
245 ; x = -x (Compass 2)
246 ; y = y
247 ; z = -z
248
249 ; Dump the accelerator data
250 rcall I2C_OneByteRX
251 movff SSP1BUF,lo ; accel_DX+0
252 rcall I2C_OneByteRX
253 movff SSP1BUF,hi ;accel_DX+1
254 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
255 btfss compass_type2 ; compass 2?
256 bra I2C_RX_accelerometer1_c1 ; No, compass 1
257 ; compass 2
258 btfss flip_screen ; 180° rotation ?
259 bra I2C_RX_accelerometer2_c1 ; No, continue with normal compass1 routines for Y and Z
260 ; flipped compass 2, negate x
261 comf hi ; 16bit sign change.
262 negf lo
263 btfsc STATUS,C ; Carry to propagate ?
264 incf hi,F ; YES: do it.
265 bra I2C_RX_accelerometer2_c1 ; continue with normal compass1 routines for Y and Z
266
267 I2C_RX_accelerometer1_c1:
268 btfsc flip_screen ; 180° rotation ?
269 bra I2C_RX_accelerometer2_c1 ; Yes
270 ; non-flipped compass 1, negate x
271 comf hi ; 16bit sign change.
272 negf lo
273 btfsc STATUS,C ; Carry to propagate ?
274 incf hi,F ; YES: do it.
275 I2C_RX_accelerometer2_c1:
276 ; flipped compass 1, non-flipped compass 2
277 movff lo,accel_DX+0
278 movff hi,accel_DX+1 ; Copy result
279 rcall I2C_OneByteRX
280 movff SSP1BUF,lo ; accel_DY+0
281 rcall I2C_OneByteRX
282 movff SSP1BUF,hi ; accel_DY+1
283
284 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
285 btfsc flip_screen ; 180° rotation ?
286 bra I2C_RX_accelerometer3_c1 ; Yes
287 comf hi ; 16bit sign change.
288 negf lo
289 btfsc STATUS,C ; Carry to propagate ?
290 incf hi,F ; YES: do it.
291 I2C_RX_accelerometer3_c1:
292 movff lo,accel_DY+0
293 movff hi,accel_DY+1 ; Copy result
294
295 rcall I2C_OneByteRX
296 movff SSP1BUF,lo ;accel_DZ+0
297 bsf SSP1CON2, RCEN ; Enable receive mode
298 rcall WaitMSSP
299 ; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+1)...
300 movff SSP1BUF,hi ;accel_DZ+1
301 bsf SSP1CON2,PEN ; Stop condition
302 rcall WaitMSSP
303 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
304 comf hi ; 16bit sign change for Z
305 negf lo
306 btfsc STATUS,C ; Carry to propagate ?
307 incf hi,F ; YES: do it.
308 movff lo,accel_DZ+0
309 movff hi,accel_DZ+1 ; Copy result
310 return
311
312 I2C_RX_accelerometer_compass2:
313 bsf SSP1CON2,SEN ; Start condition
314 rcall WaitMSSP
315 movlw 0x32 ; address
316 rcall I2C_TX
317 movlw b'10101000' ; 0x28 with auto-increment (MSB=1)
318 rcall I2C_TX
319 bsf SSP1CON2,RSEN ; Repeated start condition (!)
320 rcall WaitMSSP
321 movlw 0x33 ; address
322 bra I2C_RX_accelerometer_compass1_xx
323
324 I2C_OneByteRX:
325 bsf SSP1CON2,RCEN ; Enable receive mode
326 rcall WaitMSSP
327 bsf SSP1CON2,ACKEN ; Master acknowledge
328 bra WaitMSSP ; And return!
329
330 global I2C_RX_compass
331 I2C_RX_compass:
332 btfsc compass_type2 ; compass2
333 bra I2C_RX_compass2 ; yes
334 btfsc compass_type ; compass1?
335 bra I2C_RX_compass1 ; yes
336 I2C_RX_compass0:
337 bsf SSP1CON2,SEN ; Start condition
338 rcall WaitMSSP
339 movlw 0x3C ; address
340 rcall I2C_TX
341 movlw 0x03
342 rcall I2C_TX
343 bsf SSP1CON2,PEN ; Stop condition
344 rcall WaitMSSP
345
346 bcf PIR1,SSP1IF
347 bsf SSP1CON2,SEN ; Start condition
348 rcall WaitMSSP
349 movlw 0x3D ; address
350 rcall I2C_TX
351
352 ; Compass IC sends data in following order:
353 ; x MSB
354 ; x LSB
355 ; z MSB
356 ; z LSB
357 ; y MSB
358 ; y LSB
359
360 ; Non-flipped screen
361 ; Chip orientation on the PCB requires
362 ; Original = Corrected
363 ; x = -y
364 ; z = z
365 ; y = x
366
367 ; Flipped screen
368 ; Chip orientation on the PCB requires
369 ; Original = Corrected
370 ; x = y
371 ; z = z
372 ; y = -x
373
374 rcall I2C_OneByteRX ; Get one byte
375 movff SSP1BUF,compass_DY+1 ; Data Byte
376 rcall I2C_OneByteRX ; Get one byte
377 movff SSP1BUF,compass_DY+0 ; Data Byte
378 btfsc flip_screen ; 180° rotation ?
379 bra I2C_RX_compass0_2 ; Yes
380 banksel compass_DY
381 comf compass_DY+1 ; 16bit sign change.
382 negf compass_DY+0
383 btfsc STATUS,C ; Carry to propagate ?
384 incf compass_DY+1,F ; YES: do it.
385 I2C_RX_compass0_2:
386 banksel common
387 rcall I2C_OneByteRX ; Get one byte
388 movff SSP1BUF,compass_DZ+1 ; Data Byte
389 rcall I2C_OneByteRX ; Get one byte
390 movff SSP1BUF,compass_DZ+0 ; Data Byte
391 rcall I2C_OneByteRX ; Get one byte
392 movff SSP1BUF,compass_DX+1 ; Data Byte
393 bsf SSP1CON2, RCEN ; Enable receive mode
394 rcall WaitMSSP
395 movff SSP1BUF,compass_DX+0 ; Data Byte
396 bsf SSP1CON2,PEN ; Stop condition
397 rcall WaitMSSP
398 btfss flip_screen ; 180° rotation ?
399 return ; No, done.
400 ; Yes, flip X
401 banksel compass_DX
402 comf compass_DX+1 ; 16bit sign change.
403 negf compass_DX+0
404 btfsc STATUS,C ; Carry to propagate ?
405 incf compass_DX+1,F ; YES: do it.
406 banksel common
407 return
408
409 I2C_RX_compass1: ; New compass
410 bsf SSP1CON2,SEN ; Start condition
411 rcall WaitMSSP
412 movlw 0x3C ; address
413 rcall I2C_TX
414 movlw b'10001000' ; 0x08 with auto-increment (MSB=1)
415 rcall I2C_TX
416 bsf SSP1CON2,RSEN ; Repeated start condition (!)
417 rcall WaitMSSP
418 movlw 0x3D ; address
419 rcall I2C_TX
420 ;rcall WaitMSSP ; Needed? (mH)
421 rcall I2C_OneByteRX ; Get one byte
422 movff SSP1BUF,lo ; Data Byte
423 rcall I2C_OneByteRX ; Get one byte
424 movff SSP1BUF,hi ; Data Byte
425 rcall I2C_TwoBytesRX_div8_2
426 movff lo,compass_DX+0
427 movff hi,compass_DX+1
428 btfss flip_screen ; 180° rotation ?
429 bra I2C_RX_compass1_1 ; Yes
430 ; Yes, flip X
431 banksel compass_DX
432 comf compass_DX+1 ; 16bit sign change.
433 negf compass_DX+0
434 btfsc STATUS,C ; Carry to propagate ?
435 incf compass_DX+1,F ; YES: do it.
436 banksel common
437 I2C_RX_compass1_1:
438 rcall I2C_OneByteRX ; Get one byte
439 movff SSP1BUF,lo ; Data Byte
440 rcall I2C_OneByteRX ; Get one byte
441 movff SSP1BUF,hi ; Data Byte
442 rcall I2C_TwoBytesRX_div8_2
443 movff lo,compass_DY+0
444 movff hi,compass_DY+1
445 btfss flip_screen ; 180° rotation ?
446 bra I2C_RX_compass1_2 ; Yes
447 ; Yes, flip Y
448 banksel compass_DY
449 comf compass_DY+1 ; 16bit sign change.
450 negf compass_DY+0
451 btfsc STATUS,C ; Carry to propagate ?
452 incf compass_DY+1,F ; YES: do it.
453 I2C_RX_compass1_2:
454 banksel common
455 rcall I2C_OneByteRX ; Get one byte
456 movff SSP1BUF,lo ; Data Byte
457 bsf SSP1CON2, RCEN ; Enable receive mode
458 rcall WaitMSSP
459 movff SSP1BUF,hi ; Data Byte
460 rcall I2C_TwoBytesRX_div8_2
461 movff lo,compass_DZ+0
462 movff hi,compass_DZ+1
463 bsf SSP1CON2,PEN ; Stop condition
464 bra WaitMSSP ;(And return)
465
466 I2C_RX_compass2: ; newest compass
467 bsf SSP1CON2,SEN ; Start condition
468 rcall WaitMSSP
469 movlw 0x3C ; address
470 rcall I2C_TX
471 movlw 0xE8 ; 0x68 with auto-increment (MSB=1)
472 rcall I2C_TX
473 bsf SSP1CON2,RSEN ; Repeated start condition (!)
474 rcall WaitMSSP
475 movlw 0x3D ; address
476 rcall I2C_TX
477 ; rcall WaitMSSP
478 rcall I2C_OneByteRX ; Get one byte
479 movff SSP1BUF,lo ; Data Byte
480 rcall I2C_OneByteRX ; Get one byte
481 movff SSP1BUF,hi ; Data Byte
482 ; rcall I2C_TwoBytesRX_div8_2
483 btfsc flip_screen ; 180° rotation ?
484 bra I2C_RX_compass2_1 ; Yes, do nothing with X
485 ; No, flip X
486 comf hi ; 16bit sign change.
487 negf lo
488 btfsc STATUS,C ; Carry to propagate ?
489 incf hi,F ; YES: do it.
490 I2C_RX_compass2_1:
491 movff lo,compass_DX+0
492 movff hi,compass_DX+1
493 rcall I2C_OneByteRX ; Get one byte
494 movff SSP1BUF,lo ; Data Byte
495 rcall I2C_OneByteRX ; Get one byte
496 movff SSP1BUF,hi ; Data Byte
497 ; rcall I2C_TwoBytesRX_div8_2
498 btfss flip_screen ; 180° rotation ?
499 bra I2C_RX_compass2_2 ; No, do nothing with Y
500 ; Yes, flip Y
501 comf hi ; 16bit sign change.
502 negf lo
503 btfsc STATUS,C ; Carry to propagate ?
504 incf hi,F ; YES: do it.
505 I2C_RX_compass2_2:
506 movff lo,compass_DY+0
507 movff hi,compass_DY+1
508 rcall I2C_OneByteRX ; Get one byte
509 movff SSP1BUF,lo ; Data Byte
510 rcall I2C_OneByteRX ; Get one byte
511 movff SSP1BUF,hi ; Data Byte
512 ; rcall I2C_TwoBytesRX_div8_2
513 movff lo,compass_DZ+0
514 movff hi,compass_DZ+1
515 bsf SSP1CON2,PEN ; Stop condition
516 bra WaitMSSP ;(And return)
517
518
519 global I2C_init_compass
520 I2C_init_compass:
521 bsf compass_enabled
522 bcf compass_type2
523 ; probe compass 2
524 bsf SSP1CON2,SEN ; Start condition
525 rcall WaitMSSP
526 movlw 0x32 ; Address byte + Write bit
527 movwf SSP1BUF ; control byte
528 rcall WaitMSSP
529 btfss SSP1CON2,ACKSTAT ; ACK?
530 bsf compass_type2 ; ACK send. compass2 present
531 bsf SSP1CON2,PEN ; Stop condition
532 rcall WaitMSSP
533
534 btfsc compass_type2
535 bra I2C_init_compass2 ; Compass2
536 ; Check for compass0 or compass1...
537 bsf compass_type ; set flag
538 bsf SSP1CON2,SEN ; Start condition
539 rcall WaitMSSP
540 movlw 0x3C ; address
541 rcall I2C_TX
542 movlw 0x0F
543 rcall I2C_TX
544 bsf SSP1CON2,PEN ; Stop condition
545 rcall WaitMSSP
546 bcf PIR1,SSP1IF
547 bsf SSP1CON2,SEN ; Start condition
548 rcall WaitMSSP
549 movlw 0x3D ; address
550 rcall I2C_TX
551 rcall I2C_OneByteRX ; Get one byte
552 movlw 0x49 ; 0x49 = Compass1
553 cpfseq SSP1BUF
554 bcf compass_type ; clear flag
555 bsf SSP1CON2,PEN ; Stop condition
556 rcall WaitMSSP
557
558 btfsc compass_type ; compass1?
559 bra I2C_init_compass1 ; yes
560 ; init compass0
561 bsf SSP1CON2,SEN ; Start condition
562 rcall WaitMSSP
563 movlw 0x3C ; address
564 rcall I2C_TX
565 movlw 0x00
566 rcall I2C_TX
567 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias)
568 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged
569 rcall I2C_TX
570 I2C_init_compass_common:
571 movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss)
572 swapf i2c_temp1,F
573 comf i2c_temp1,F
574 bcf STATUS,C
575 rlcf i2c_temp1
576 movf i2c_temp1,W
577 clrf i2c_temp1
578 rcall I2C_TX
579 movlw b'00000000' ; Continuous Mode
580 rcall I2C_TX
581 bsf SSP1CON2,PEN ; Stop condition
582 bra WaitMSSP ; (And return)
583
584 I2C_init_compass1:
585 bsf SSP1CON2,SEN ; Start condition
586 rcall WaitMSSP
587 movlw 0x3C ; address
588 rcall I2C_TX
589 movlw 0x9F ; 1F with auto-increment (MSB=1)
590 rcall I2C_TX
591 movlw b'00000000' ; CTRL0
592 rcall I2C_TX
593 movlw b'00101111' ; CTRL1 (6,25Hz, BDU=0, x,y,z = ON)
594 rcall I2C_TX
595 movlw b'11000000' ; CTRL2 (50Hz, +/-2g,
596 rcall I2C_TX
597 movlw b'00000000' ; CTRL3
598 rcall I2C_TX
599 movlw b'00000000' ; CTRL4
600 rcall I2C_TX
601 movlw b'01100100' ; CTRL5 HIGH res, 6,25Hz
602 rcall I2C_TX
603 init_compass1_common:
604 movff opt_compass_gain,i2c_temp1 ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) +++
605 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
606 dcfsnz i2c_temp1,F ; = 1?
607 movlw b'01100000' ; Yes, CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
608 dcfsnz i2c_temp1,F ; = 2?
609 movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss)
610 dcfsnz i2c_temp1,F ; = 3?
611 movlw b'01000000' ; Yes, CTRL6 (+/-8 Gauss)
612 dcfsnz i2c_temp1,F ; = 4?
613 movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss)
614 dcfsnz i2c_temp1,F ; = 5?
615 movlw b'00100000' ; Yes, CTRL6 (+/-4 Gauss)
616 dcfsnz i2c_temp1,F ; = 6?
617 movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss)
618 dcfsnz i2c_temp1,F ; = 7?
619 movlw b'00000000' ; Yes, CTRL6 (+/-2 Gauss)
620 rcall I2C_TX
621 movlw b'00000000' ; CTRL7 Continuous Mode
622 rcall I2C_TX
623 bsf SSP1CON2,PEN ; Stop condition
624 bra WaitMSSP ; (And return)
625
626 I2C_init_compass2:
627 bsf SSP1CON2,SEN ; Start condition
628 rcall WaitMSSP
629 movlw 0x3C ; address
630 rcall I2C_TX
631 movlw 0xE0 ; 0x60 with auto-increment (MSB=1)
632 rcall I2C_TX
633 movlw b'00000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60
634 rcall I2C_TX
635 movlw b'00000000' ; CFG_REG_B_M (Low-Pass Filter off) 0x61 (set pulse is released every 63 ODR)
636 rcall I2C_TX
637 movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62
638 rcall I2C_TX
639 bsf SSP1CON2,PEN ; Stop condition
640 bra WaitMSSP ;(And return)
641
642
643 global I2C_sleep_compass
644 I2C_sleep_compass:
645 bcf compass_enabled
646 btfsc compass_type2 ; compass2?
647 bra I2C_sleep_compass2 ; yes
648 btfsc compass_type ; compass1?
649 bra I2C_sleep_compass1 ; yes
650 I2C_sleep_compass0:
651 bsf SSP1CON2,SEN ; Start condition
652 rcall WaitMSSP
653 movlw 0x3C ; address
654 rcall I2C_TX
655 movlw 0x00
656 rcall I2C_TX
657 movlw b'01101000' ; ConfigA
658 rcall I2C_TX
659 movlw b'00100000' ; ConfigB
660 rcall I2C_TX
661 movlw b'00000010' ; Idle Mode
662 rcall I2C_TX
663 bsf SSP1CON2,PEN ; Stop condition
664 bra WaitMSSP ; (And return)
665
666 I2C_sleep_compass1:
667 bsf SSP1CON2,SEN ; Start condition
668 rcall WaitMSSP
669 movlw 0x3C ; address
670 rcall I2C_TX
671 movlw 0x20 ; CTRL_REG1
672 rcall I2C_TX
673 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor Power-down mode
674 rcall I2C_TX
675 bsf SSP1CON2,PEN ; Stop condition
676 rcall WaitMSSP
677 bsf SSP1CON2,SEN ; Start condition
678 rcall WaitMSSP
679 movlw 0x3C ; address
680 rcall I2C_TX
681 movlw 0x26 ; CTRL_REG7
682 rcall I2C_TX
683 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor Power-down mode
684 rcall I2C_TX
685 bsf SSP1CON2,PEN ; Stop condition
686 bra WaitMSSP ;(And return)
687
688 I2C_sleep_compass2:
689 ; magnetic
690 bsf SSP1CON2,SEN ; Start condition
691 rcall WaitMSSP
692 movlw 0x3C ; address
693 rcall I2C_TX
694 movlw 0xE0 ; 0x60 with auto-increment (MSB=1)
695 rcall I2C_TX
696 movlw b'00000011' ; CFG_REG_A_M (Idle mode) 0x60
697 rcall I2C_TX
698 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition)
699 rcall I2C_TX
700 movlw b'01010001' ; CFG_REG_C_M 0x62
701 rcall I2C_TX
702 movlw b'00000000' ; INT_CTRL_REG_M 0x63
703 rcall I2C_TX
704
705 bsf SSP1CON2,PEN ; Stop condition
706 bra WaitMSSP ; (And return)
707 722
708 I2C_sleep_accelerometer2:
709 ; accelerometer
710 bsf SSP1CON2,SEN ; Start condition
711 rcall WaitMSSP
712 movlw 0x32 ; address
713 rcall I2C_TX
714 movlw 0x9F ; 1F with auto-increment (MSB=1)
715 rcall I2C_TX
716 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) 0x1F
717 rcall I2C_TX
718 movlw b'00000000' ; CTRL_REG1_A (All off) 0x20
719 rcall I2C_TX
720 bsf SSP1CON2,PEN ; Stop condition
721 bra WaitMSSP ; (And return)
722
723 global I2C_init_accelerometer 723 global I2C_init_accelerometer
724 I2C_init_accelerometer: 724 I2C_init_accelerometer:
725 btfsc compass_type2 ; compass2? 725 btfsc compass_type2 ; compass2?
726 bra I2C_init_accelerometer2 ; Yes. 726 bra I2C_init_accelerometer2 ; Yes.
727 727
890 890
891 tstfsz batt_voltage+1 ; <256mV? 891 tstfsz batt_voltage+1 ; <256mV?
892 return ; No, done. 892 return ; No, done.
893 bra lt2942_init ;(and return) 893 bra lt2942_init ;(and return)
894 894
895 ; global lt2942_get_temperature 895 global lt2942_get_temperature
896 ;lt2942_get_temperature: ; Read temperature registers 896 lt2942_get_temperature: ; Read temperature registers
897 ; clrf i2c_temp1 897 clrf i2c_temp1
898 ; movlw 0x0C ; Point to temperature registers 898 movlw 0x0C ; Point to temperature registers
899 ; call I2C_TX_GAUGE 899 call I2C_TX_GAUGE
900 ; call I2C_RX 900 call I2C_RX_GAUGE
901 ; bsf SSP1CON2,ACKEN ; Master acknowledge 901 bsf SSP1CON2,ACKEN ; Master acknowlegde
902 ; rcall WaitMSSP 902 rcall WaitMSSP
903 ; movff SSP1BUF,xA+1 903 movff SSP1BUF,xA+1
904 ; bsf SSP1CON2, RCEN ; Enable receive mode 904 bsf SSP1CON2, RCEN ; Enable recieve mode
905 ; rcall WaitMSSP 905 rcall WaitMSSP
906 ; movff SSP1BUF,xA+0 906 movff SSP1BUF,xA+0
907 ; bsf SSP1CON2,PEN ; Stop condition 907 bsf SSP1CON2,PEN ; Stop condition
908 ; rcall WaitMSSP 908 rcall WaitMSSP
909 ; 909
910 ;; banksel common 910 ; banksel common
911 ; ; xA:2 loaded with raw values 911 ; xA:2 loaded with raw values
912 ; movlw LOW .6000 912 movlw LOW .6000
913 ; movwf xB+0 913 movwf xB+0
914 ; movlw HIGH .6000 914 movlw HIGH .6000
915 ; movwf xB+1 915 movwf xB+1
916 ; call mult16x16 ; xA*xB=xC 916 call mult16x16 ;xA*xB=xC
917 ; 917
918 ; ; devide xC (32bit)/65535 for result in 0.1K (16bit) 918 ; devide xC (32bit)/65535 for result in 0.1K (16bit)
919 ; movlw .16 919 movlw .16
920 ; movwf i2c_temp1 920 movwf i2c_temp1
921 ;lt2942_get_temperature2: 921 lt2942_get_temperature2:
922 ; bcf STATUS,C 922 bcf STATUS,C
923 ; rrcf xC+3,F 923 rrcf xC+3,F
924 ; rrcf xC+2,F 924 rrcf xC+2,F
925 ; rrcf xC+1,F 925 rrcf xC+1,F
926 ; rrcf xC+0,F 926 rrcf xC+0,F
927 ; decfsz i2c_temp1,F 927 decfsz i2c_temp1,F
928 ; bra lt2942_get_temperature2 928 bra lt2942_get_temperature2
929 ; 929
930 ; movff xC+1,sub_a+1 930 movff xC+1,sub_a+1
931 ; movff xC+0,sub_a+0 931 movff xC+0,sub_a+0
932 ; movlw LOW .2731 ; Kelvin to Celsius offset 932 movlw LOW .2731 ; Kelvin to Celcius offset
933 ; movwf sub_b+0 933 movwf sub_b+0
934 ; movlw HIGH .2731 ; Kelvin to Celsius offset 934 movlw HIGH .2731 ; Kelvin to Celcius offset
935 ; movwf sub_b+1 935 movwf sub_b+1
936 ; call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) 936 call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values)
937 ; 937
938 ; ; Update batttery_temperature in 0.1°C 938 ; Update battery_temperature in 0.1°C
939 ; movff sub_c+1,battery_temperature+1 939 movff sub_c+1,battery_temperature+1
940 ; movff sub_c+0,battery_temperature+0 940 movff sub_c+0,battery_temperature+0
941 ; return 941
942 movlw LOW max_allowed_battery_temp ; in 0.1°C
943 movwf sub_a+0
944 movlw HIGH max_allowed_battery_temp
945 movwf sub_a+1
946 movff battery_temperature+0,sub_b+0
947 movff battery_temperature+1,sub_b+1
948 call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values)
949 btfss neg_flag
950 return ; temp ok, return
951 ; too hot, disable charge if currently charging
952 btfss cc_active
953 return ; Not charging, return
954 ; charging: Disable now
955 bsf charge_disable
956 bcf TRISE,2
957 bsf battery_overtemp ; =1: The battery was charged and temp was too high (Only cleared on POR)
958 return
942 959
943 global lt2942_get_accumulated_charge 960 global lt2942_get_accumulated_charge
944 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent 961 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent
945 clrf i2c_temp1 962 clrf i2c_temp1
946 movlw 0x00 ; Point to status register 963 movlw 0x00 ; Point to status register