comparison src/i2c.asm @ 656:8af5aefbcdaf default tip

Update to 3.31 beta
author heinrichsweikamp
date Thu, 27 Nov 2025 18:32:58 +0100
parents c7b7b8a358cd
children
comparison
equal deleted inserted replaced
655:c7b7b8a358cd 656:8af5aefbcdaf
40 ; 40 ;
41 ; Battery gauge 41 ; Battery gauge
42 ; ------------- 42 ; -------------
43 ; LTC2942 read address (8-Bit): 0xC9 43 ; LTC2942 read address (8-Bit): 0xC9
44 ; LTC2942 write address (8-Bit): 0xC8 44 ; LTC2942 write address (8-Bit): 0xC8
45 ;
46 ; Alternative Battery gauge
47 ; -------------
48 ; LTC2959 read address (8-Bit): 0xC7
49 ; LTC2959 write address (8-Bit): 0xC6
45 ; 50 ;
46 ; Alternative pressure sensor 51 ; Alternative pressure sensor
47 ; ----------- 52 ; -----------
48 ; MS5837 read address (8-Bit): 0xED 53 ; MS5837 read address (8-Bit): 0xED
49 ; MS5837 write address (8-Bit): 0xEC 54 ; MS5837 write address (8-Bit): 0xEC
118 btfsc compass_type1 ; compass1 ? 123 btfsc compass_type1 ; compass1 ?
119 bra I2C_RX_accelerometer_compass1 ; YES 124 bra I2C_RX_accelerometer_compass1 ; YES
120 ;bra I2C_RX_accelerometer_compass0 ; NO - compass0 then 125 ;bra I2C_RX_accelerometer_compass0 ; NO - compass0 then
121 126
122 ;I2C_RX_accelerometer_compass0: 127 ;I2C_RX_accelerometer_compass0:
123 bsf SSP1CON2,SEN ; start condition 128 rcall I2C_SEN ; start condition
124 rcall WaitMSSP ; wait for TX to complete
125 movlw 0x38 ; address 129 movlw 0x38 ; address
126 movff WREG,i2c_error_vault+0 ; Store address
127 rcall I2C_TX ; send byte 130 rcall I2C_TX ; send byte
128 movlw 0x00 ; ?? 131 movlw 0x00 ; ??
129 rcall I2C_TX ; send byte 132 rcall I2C_TX ; send byte
130 bsf SSP1CON2,RSEN ; repeated start condition 133 rcall I2C_RSEN ; repeated start condition
131 rcall WaitMSSP ; wait for TX to complete
132 movlw 0x39 ; address 134 movlw 0x39 ; address
133 rcall I2C_TX ; send byte 135 rcall I2C_TX ; send byte
134 rcall I2C_OneByteRX ; get status byte 136 rcall I2C_OneByteRX ; get status byte
135 movf SSP1BUF,W ; copy status byte to WREG 137 movf SSP1BUF,W ; copy status byte to WREG
136 138
168 I2C_RX_accelerometer3: 170 I2C_RX_accelerometer3:
169 MOVII mpr,accel_DY ; copy result to accel_DY 171 MOVII mpr,accel_DY ; copy result to accel_DY
170 172
171 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 173 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
172 movff SSP1BUF,hi ; copy data byte to hi 174 movff SSP1BUF,hi ; copy data byte to hi
173 bsf SSP1CON2,RCEN ; enable receive mode 175 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge
174 rcall WaitMSSP ; wait for TX to complete
175 ; according to data sheet there should be no master acknowledge for the last byte (accel_DZ+0)...
176 movff SSP1BUF,lo ; copy data byte to lo 176 movff SSP1BUF,lo ; copy data byte to lo
177 rcall I2C_TwoBytesRX_div16_2 ; divide hi:lo/16 (signed) 177 rcall I2C_TwoBytesRX_div16_2 ; divide hi:lo/16 (signed)
178 comf hi ; 16 bit sign change 178 comf hi ; 16 bit sign change
179 negf lo ; ... 179 negf lo ; ...
180 btfsc STATUS,C ; carry to propagate? 180 btfsc STATUS,C ; carry to propagate?
181 incf hi,F ; YES - do it 181 incf hi,F ; YES - do it
182 MOVII mpr,accel_DZ ; copy result to accel_DZ 182 MOVII mpr,accel_DZ ; copy result to accel_DZ
183 bsf SSP1CON2,PEN ; stop condition 183 bra I2C_PEN ; stop condition
184 rcall WaitMSSP ; wait for TX to complete
185 return
186 184
187 185
188 I2C_RX_accelerometer_compass1: 186 I2C_RX_accelerometer_compass1:
189 bsf SSP1CON2,SEN ; start condition 187 rcall I2C_SEN ; start condition
190 rcall WaitMSSP ; wait for TX to complete
191 movlw 0x3C ; address 188 movlw 0x3C ; address
192 movff WREG,i2c_error_vault+0 ; Store address
193 rcall I2C_TX ; send byte 189 rcall I2C_TX ; send byte
194 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) 190 movlw b'10101000' ; 0x28 with auto-increment (MSB=1)
195 rcall I2C_TX ; send byte 191 rcall I2C_TX ; send byte
196 bsf SSP1CON2,RSEN ; repeated start condition (!) 192 rcall I2C_RSEN ; repeated start condition
197 rcall WaitMSSP ; wait for TX to complete
198 movlw 0x3D ; address 193 movlw 0x3D ; address
199 194
200 I2C_RX_accelerometer_common: ; common part for compass 1,2 and 3 195 I2C_RX_accelerometer_common: ; common part for compass 1,2 and 3
201 rcall I2C_TX ; send byte 196 rcall I2C_TX ; send byte
202 197
258 incf hi,F ; YES - do it 253 incf hi,F ; YES - do it
259 I2C_RX_accelerometer3_c1: 254 I2C_RX_accelerometer3_c1:
260 MOVII mpr,accel_DY ; copy result 255 MOVII mpr,accel_DY ; copy result
261 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 256 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
262 movff SSP1BUF,lo ; accel_DZ+0 257 movff SSP1BUF,lo ; accel_DZ+0
263 bsf SSP1CON2,RCEN ; enable receive mode 258 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge
264 rcall WaitMSSP ; wait for TX to complete
265 ; according to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)...
266 movff SSP1BUF,hi ; accel_DZ+1 259 movff SSP1BUF,hi ; accel_DZ+1
267 bsf SSP1CON2,PEN ; stop condition 260 rcall I2C_PEN ; stop condition
268 rcall WaitMSSP ; wait for TX to complete
269 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only 261 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only
270 comf hi ; 16 bit sign change for Z 262 comf hi ; 16 bit sign change for Z
271 negf lo ; ... 263 negf lo ; ...
272 btfsc STATUS,C ; carry to propagate? 264 btfsc STATUS,C ; carry to propagate?
273 incf hi,F ; YES - do it 265 incf hi,F ; YES - do it
274 MOVII mpr,accel_DZ ; copy result 266 MOVII mpr,accel_DZ ; copy result
275 return ; done 267 return ; done
276 268
277 269
278 I2C_RX_accelerometer_compass2: 270 I2C_RX_accelerometer_compass2:
279 bsf SSP1CON2,SEN ; start condition 271 rcall I2C_SEN ; start condition
280 rcall WaitMSSP ; wait for TX to complete
281 movlw 0x32 ; address 272 movlw 0x32 ; address
282 movff WREG,i2c_error_vault+0 ; Store address
283 rcall I2C_TX ; send byte 273 rcall I2C_TX ; send byte
284 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) 274 movlw b'10101000' ; 0x28 with auto-increment (MSB=1)
285 rcall I2C_TX ; send byte 275 rcall I2C_TX ; send byte
286 bsf SSP1CON2,RSEN ; repeated start condition (!) 276 rcall I2C_RSEN ; repeated start condition
287 rcall WaitMSSP ; wait for TX to complete
288 movlw 0x33 ; address 277 movlw 0x33 ; address
289 bra I2C_RX_accelerometer_common ; continue with common part 278 bra I2C_RX_accelerometer_common ; continue with common part
290 279
291 I2C_RX_accelerometer_compass3: 280 I2C_RX_accelerometer_compass3:
292 bsf SSP1CON2,SEN ; start condition 281 rcall I2C_SEN ; start condition
293 rcall WaitMSSP ; wait for TX to complete
294 movlw 0x3A ; address 282 movlw 0x3A ; address
295 movff WREG,i2c_error_vault+0 ; Store address
296 rcall I2C_TX ; send byte 283 rcall I2C_TX ; send byte
297 movlw 0x28 ; 0x28 (OUT_X_L_A) 284 movlw 0x28 ; 0x28 (OUT_X_L_A)
298 rcall I2C_TX ; send byte 285 rcall I2C_TX ; send byte
299 bsf SSP1CON2,RSEN ; repeated start condition (!) 286 rcall I2C_RSEN ; repeated start condition
300 rcall WaitMSSP ; wait for TX to complete
301 movlw 0x3B ; address 287 movlw 0x3B ; address
302 bra I2C_RX_accelerometer_common ; continue with common part 288 bra I2C_RX_accelerometer_common ; continue with common part
303 289
304
305 ;-----------------------------------------------------------------------------
306 ; Helper Function - receive 1 Byte with Acknowledge
307 ;
308 I2C_OneByteRX:
309 bsf SSP1CON2,RCEN ; enable receive mode
310 rcall WaitMSSP ; wait for TX to complete
311 bsf SSP1CON2,ACKEN ; send master acknowledge
312 bra WaitMSSP ; wait for TX to complete and return
313 290
314 291
315 ;----------------------------------------------------------------------------- 292 ;-----------------------------------------------------------------------------
316 ; Read Compass 293 ; Read Compass
317 ; 294 ;
326 btfsc compass_type1 ; compass 1 ? 303 btfsc compass_type1 ; compass 1 ?
327 bra I2C_RX_compass1 ; YES 304 bra I2C_RX_compass1 ; YES
328 ;bra I2C_RX_compass0 ; NO - compass 0 then 305 ;bra I2C_RX_compass0 ; NO - compass 0 then
329 306
330 ;I2C_RX_compass0: 307 ;I2C_RX_compass0:
331 bsf SSP1CON2,SEN ; start condition 308 rcall I2C_SEN ; start condition
332 rcall WaitMSSP ; wait for TX to complete 309 movlw 0x3C ; address + write bit
333 movlw 0x3C ; address 310 rcall I2C_TX ; send byte
334 movff WREG,i2c_error_vault+0 ; Store address 311 movlw 0x03 ; Point to Data Output X MSB Register (0x03)
335 rcall I2C_TX ; send byte 312 rcall I2C_TX ; send byte
336 movlw 0x03 ; ?? 313 rcall I2C_PEN ; stop condition
337 rcall I2C_TX ; send byte 314 rcall I2C_SEN ; start condition
338 bsf SSP1CON2,PEN ; stop condition 315 movlw 0x3D ; address + read bit
339 rcall WaitMSSP ; wait for TX to complete
340 bsf SSP1CON2,SEN ; start condition
341 rcall WaitMSSP ; wait for TX to complete
342 movlw 0x3D ; address
343 rcall I2C_TX ; send byte 316 rcall I2C_TX ; send byte
344 317
345 ; Compass IC sends data in following order: 318 ; Compass IC sends data in following order:
346 ; x MSB 319 ; x MSB
347 ; x LSB 320 ; x LSB
381 movff SSP1BUF,compass_DZ+1 ; data byte 354 movff SSP1BUF,compass_DZ+1 ; data byte
382 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 355 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
383 movff SSP1BUF,compass_DZ+0 ; data byte 356 movff SSP1BUF,compass_DZ+0 ; data byte
384 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 357 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
385 movff SSP1BUF,compass_DX+1 ; data byte 358 movff SSP1BUF,compass_DX+1 ; data byte
386 bsf SSP1CON2,RCEN ; enable receive mode 359 rcall I2C_RCEN ; enable receive mode
387 rcall WaitMSSP ; wait for TX to complete
388 movff SSP1BUF,compass_DX+0 ; data byte 360 movff SSP1BUF,compass_DX+0 ; data byte
389 bsf SSP1CON2,PEN ; stop condition 361 rcall I2C_PEN ; stop condition
390 rcall WaitMSSP ; wait for TX to complete
391 btfss flip_screen ; 180° rotation? 362 btfss flip_screen ; 180° rotation?
392 return ; NO - done 363 return ; NO - done
393 banksel compass_DX ; YES - flip X 364 banksel compass_DX ; YES - flip X
394 comf compass_DX+1 ; - 16 bit sign change 365 comf compass_DX+1 ; - 16 bit sign change
395 negf compass_DX+0 366 negf compass_DX+0
398 banksel common ; back to bank common 369 banksel common ; back to bank common
399 return ; done 370 return ; done
400 371
401 372
402 I2C_RX_compass1: ; compass type 1 373 I2C_RX_compass1: ; compass type 1
403 bsf SSP1CON2,SEN ; start condition 374 rcall I2C_SEN ; start condition
404 rcall WaitMSSP ; wait for TX to complete
405 movlw 0x3C ; address 375 movlw 0x3C ; address
406 movff WREG,i2c_error_vault+0 ; Store address
407 rcall I2C_TX ; send byte 376 rcall I2C_TX ; send byte
408 movlw b'10001000' ; 0x08 with auto-increment (MSB=1) 377 movlw b'10001000' ; 0x08 with auto-increment (MSB=1)
409 rcall I2C_TX ; send byte 378 rcall I2C_TX ; send byte
410 bsf SSP1CON2,RSEN ; repeated start condition (!) 379 rcall I2C_RSEN ; repeated start condition
411 rcall WaitMSSP ; wait for TX to complete
412 movlw 0x3D ; address 380 movlw 0x3D ; address
413 rcall I2C_TX ; send byte 381 rcall I2C_TX ; send byte
414 ;rcall WaitMSSP ; TODO needed? (mH) 382 ;rcall WaitMSSP ; TODO needed? (mH)
415 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 383 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
416 movff SSP1BUF,lo ; data byte 384 movff SSP1BUF,lo ; data byte
442 incf compass_DY+1,F ; YES - do it 410 incf compass_DY+1,F ; YES - do it
443 banksel common 411 banksel common
444 I2C_RX_compass1_2: 412 I2C_RX_compass1_2:
445 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 413 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
446 movff SSP1BUF,lo ; data byte 414 movff SSP1BUF,lo ; data byte
447 bsf SSP1CON2, RCEN ; Enable receive mode 415 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge
448 rcall WaitMSSP ; wait for TX to complete
449 movff SSP1BUF,hi ; data byte 416 movff SSP1BUF,hi ; data byte
450 rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) 417 rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed)
451 MOVII mpr,compass_DZ ; copy result 418 MOVII mpr,compass_DZ ; copy result
452 bsf SSP1CON2,PEN ; stop condition 419 bra I2C_PEN ; stop condition
453 rcall WaitMSSP
454 return ; done
455 420
456 421
457 422
458 I2C_RX_compass2: ; compass type 2 423 I2C_RX_compass2: ; compass type 2
459 bsf SSP1CON2,SEN ; start condition 424 rcall I2C_SEN ; start condition
460 rcall WaitMSSP ; wait for TX to complete
461 movlw 0x3C ; address 425 movlw 0x3C ; address
462 movff WREG,i2c_error_vault+0 ; Store address
463 rcall I2C_TX ; send byte 426 rcall I2C_TX ; send byte
464 movlw 0xE8 ; 0x68 with auto-increment (MSB=1) 427 movlw 0xE8 ; 0x68 with auto-increment (MSB=1)
465 rcall I2C_TX ; send byte 428 rcall I2C_TX ; send byte
466 bsf SSP1CON2,RSEN ; repeated start condition (!) 429 rcall I2C_RSEN ; repeated start condition
467 rcall WaitMSSP ; wait for TX to complete
468 movlw 0x3D ; address 430 movlw 0x3D ; address
469 rcall I2C_TX ; send byte 431 rcall I2C_TX ; send byte
470 I2C_RX_compass2_xx: ; compass 3 joins in here 432 I2C_RX_compass2_xx: ; compass 3 joins in here
471 ; rcall WaitMSSP ; wait for TX to complete (not needed, as included in I2C_TX) 433 ; rcall WaitMSSP ; wait for TX to complete (not needed, as included in I2C_TX)
472 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 434 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
497 incf hi,F ; YES - do it 459 incf hi,F ; YES - do it
498 I2C_RX_compass2_2: 460 I2C_RX_compass2_2:
499 MOVII mpr,compass_DY 461 MOVII mpr,compass_DY
500 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 462 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
501 movff SSP1BUF,lo ; data byte 463 movff SSP1BUF,lo ; data byte
502 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 464 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge
503 movff SSP1BUF,hi ; data byte 465 movff SSP1BUF,hi ; data byte
504 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) 466 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed)
505 MOVII mpr,compass_DZ ; copy result 467 MOVII mpr,compass_DZ ; copy result
506 bsf SSP1CON2,PEN ; stop condition 468 bra I2C_PEN ; stop condition
507 rcall WaitMSSP
508 return ; done
509 469
510 470
511 471
512 I2C_RX_compass3: ; compass type 3 472 I2C_RX_compass3: ; compass type 3
513 bsf SSP1CON2,SEN ; start condition 473 rcall I2C_SEN ; start condition
514 rcall WaitMSSP ; wait for TX to complete
515 movlw 0x3C ; address 474 movlw 0x3C ; address
516 movff WREG,i2c_error_vault+0 ; Store address
517 rcall I2C_TX ; send byte 475 rcall I2C_TX ; send byte
518 movlw 0xA8 ; 0x28 with auto-increment (MSB=1) 476 movlw 0xA8 ; 0x28 with auto-increment (MSB=1)
519 rcall I2C_TX ; send byte 477 rcall I2C_TX ; send byte
520 bsf SSP1CON2,RSEN ; repeated start condition (!) 478 rcall I2C_RSEN ; repeated start condition
521 rcall WaitMSSP ; wait for TX to complete
522 movlw 0x3D ; address 479 movlw 0x3D ; address
523 rcall I2C_TX ; send byte 480 rcall I2C_TX ; send byte
524 bra I2C_RX_compass2_xx ; join with compass 2 code 481 bra I2C_RX_compass2_xx ; join with compass 2 code
525 482
526 ENDIF ; _compass 483 ENDIF ; _compass
529 ;----------------------------------------------------------------------------- 486 ;-----------------------------------------------------------------------------
530 ; Initialize Compass / Accelerometer Chip 487 ; Initialize Compass / Accelerometer Chip
531 ; 488 ;
532 global I2C_init_compass 489 global I2C_init_compass
533 I2C_init_compass: 490 I2C_init_compass:
491 bsf compass_present ; Set global compass flag
534 bsf compass_enabled ; flag compass will be enabled 492 bsf compass_enabled ; flag compass will be enabled
535 bcf compass_type2 ; clear in preparation of chip detection 493 bcf compass_type2 ; clear in preparation of chip detection
536 bcf compass_type3 ; ... 494 bcf compass_type3 ; ...
537 495
538 ; probe for compass 3 496 ; probe for compass 3
539 bsf SSP1CON2,SEN ; start condition 497 rcall I2C_SEN ; start condition
540 rcall WaitMSSP ; wait for TX to complete
541 movlw 0x3A ; address byte + write bit 498 movlw 0x3A ; address byte + write bit
542 movff WREG,i2c_error_vault+0 ; Store address
543 movwf SSP1BUF ; control byte 499 movwf SSP1BUF ; control byte
544 rcall WaitMSSP ; wait for TX to complete 500 rcall WaitMSSP ; wait for TX to complete
501 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
545 btfss SSP1CON2,ACKSTAT ; ACK received? 502 btfss SSP1CON2,ACKSTAT ; ACK received?
546 bsf compass_type3 ; YES - ACK was send, compass 3 found 503 bsf compass_type3 ; YES - ACK was send, compass 3 found
547 bsf SSP1CON2,PEN ; stop condition 504 rcall I2C_PEN ; stop condition
548 rcall WaitMSSP ; wait for TX to complete
549 505
550 btfsc compass_type3 ; compass 3 found? 506 btfsc compass_type3 ; compass 3 found?
551 bra I2C_init_compass3 ; YES - initialize compass 3 507 bra I2C_init_compass3 ; YES - initialize compass 3
552 508
553 ; probe for compass 2 509 ; probe for compass 2
554 bsf SSP1CON2,SEN ; start condition 510 rcall I2C_SEN ; start condition
555 rcall WaitMSSP ; wait for TX to complete
556 movlw 0x32 ; address byte + write bit 511 movlw 0x32 ; address byte + write bit
557 movff WREG,i2c_error_vault+0 ; Store address
558 movwf SSP1BUF ; control byte 512 movwf SSP1BUF ; control byte
559 rcall WaitMSSP ; wait for TX to complete 513 rcall WaitMSSP ; wait for TX to complete
560 btfss SSP1CON2,ACKSTAT ; ACK received? 514 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
515 btfss SSP1CON2,ACKSTAT ; ACK received?
561 bsf compass_type2 ; YES - ACK send, compass 2 found 516 bsf compass_type2 ; YES - ACK send, compass 2 found
562 bsf SSP1CON2,PEN ; stop condition 517 rcall I2C_PEN ; stop condition
563 rcall WaitMSSP ; wait for TX to complete
564 518
565 btfsc compass_type2 ; compass 2 found? 519 btfsc compass_type2 ; compass 2 found?
566 bra I2C_init_compass2 ; YES - initialize compass 2 520 bra I2C_init_compass2 ; YES - initialize compass 2
567 521
568 ; probe for compass 0 or 1 522 ; probe for compass 1
569 bsf compass_type1 ; assume compass 1 by default 523 bsf compass_type1 ; assume compass 1 by default
570 bsf SSP1CON2,SEN ; start condition 524 rcall I2C_SEN ; start condition
571 rcall WaitMSSP ; wait for TX to complete
572 movlw 0x3C ; address 525 movlw 0x3C ; address
573 movff WREG,i2c_error_vault+0 ; Store address
574 rcall I2C_TX ; send byte 526 rcall I2C_TX ; send byte
575 movlw 0x0F ; ?? 527 movlw 0x0F ; ??
576 rcall I2C_TX ; send byte 528 rcall I2C_TX ; send byte
577 bsf SSP1CON2,PEN ; stop condition 529 rcall I2C_PEN ; stop condition
578 rcall WaitMSSP ; wait for TX to complete 530 rcall I2C_SEN ; start condition
579 bsf SSP1CON2,SEN ; start condition
580 rcall WaitMSSP ; wait for TX to complete
581 movlw 0x3D ; address 531 movlw 0x3D ; address
582 rcall I2C_TX ; send byte 532 rcall I2C_TX ; send byte
583 rcall I2C_OneByteRX ; receive 1 byte with acknowledge 533 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
584 movlw 0x49 ; 0x49 = compass 1 534 movlw 0x49 ; 0x49 = compass 1
585 cpfseq SSP1BUF ; 0x49 received? 535 cpfseq SSP1BUF ; 0x49 received?
586 bcf compass_type1 ; NO - clear flag for compass 1 536 bcf compass_type1 ; NO - clear flag for compass 1
587 bsf SSP1CON2,PEN ; stop condition 537 rcall I2C_PEN ; stop condition
588 rcall WaitMSSP ; wait for TX to complete
589 538
590 btfsc compass_type1 ; compass 1 found? 539 btfsc compass_type1 ; compass 1 found?
591 bra I2C_init_compass1 ; YES - initialize compass 1 540 bra I2C_init_compass1 ; YES - initialize compass 1
592 ;bra I2C_init_compass0 ; NO - must be compass 0 then 541
542 ; probe for compass 0
543 bsf compass_type0 ; assume compass 0 by default
544 rcall I2C_SEN ; start condition
545 movlw 0x3C ; address + write bit
546 rcall I2C_TX ; send byte
547 movlw 0x0A ; Point to Identification Register A
548 rcall I2C_TX ; send byte
549 rcall I2C_PEN ; stop condition
550 rcall I2C_SEN ; start condition
551 movlw 0x3D ; address + read bit
552 rcall I2C_TX ; send byte
553 rcall I2C_OneByteRX ; receive 1 byte with acknowledge
554 movlw b'01001000' ; Identification Register A must be "H"
555 cpfseq SSP1BUF ; Compare with received value
556 bcf compass_type0 ; Not equal -> Not compass 0
557 rcall I2C_PEN ; stop condition
558
559 btfsc compass_type0 ; compass 0 found?
560 bra I2C_init_compass0 ; YES - initialize compass 0
561 ; ; no compass of any type found
562 bcf compass_present ; Delete global compass flag
563 return
593 564
594 565
595 I2C_init_compass0: 566 I2C_init_compass0:
596 ; magnetic 567 ; magnetic
597 bsf SSP1CON2,SEN ; start condition 568 rcall I2C_SEN ; start condition
598 rcall WaitMSSP ; wait for TX to complete
599 movlw 0x3C ; address 569 movlw 0x3C ; address
600 movff WREG,i2c_error_vault+0 ; Store address
601 rcall I2C_TX ; send byte 570 rcall I2C_TX ; send byte
602 movlw 0x00 ; ?? 571 movlw 0x00 ; ??
603 rcall I2C_TX ; send byte 572 rcall I2C_TX ; send byte
604 movlw b'01101000' ; ConfigA: 3 Hz, 8 samples averaged 573 movlw b'01101000' ; ConfigA: 3 Hz, 8 samples averaged
605 rcall I2C_TX ; send byte 574 rcall I2C_TX ; send byte
610 rlcf i2c_temp1 ; 579 rlcf i2c_temp1 ;
611 movf i2c_temp1,W ; 580 movf i2c_temp1,W ;
612 rcall I2C_TX ; send byte 581 rcall I2C_TX ; send byte
613 movlw b'00000000' ; select continuous mode 582 movlw b'00000000' ; select continuous mode
614 rcall I2C_TX ; send byte 583 rcall I2C_TX ; send byte
615 bsf SSP1CON2,PEN ; stop condition 584 rcall I2C_PEN ; stop condition
616 rcall WaitMSSP ; wait for TX to complete
617 585
618 ; accelerometer 586 ; accelerometer
619 rcall I2C_sleep_accelerometer0 ; registers can only be changed in standby mode 587 rcall I2C_sleep_accelerometer0 ; registers can only be changed in standby mode
620 588
621 bsf SSP1CON2,SEN ; start condition 589 rcall I2C_SEN ; start condition
622 rcall WaitMSSP ; wait for TX to complete
623 movlw 0x38 ; address 590 movlw 0x38 ; address
624 movff WREG,i2c_error_vault+0 ; Store address
625 rcall I2C_TX ; send byte 591 rcall I2C_TX ; send byte
626 movlw 0x0E ; XYZ_DATA_CFG 592 movlw 0x0E ; XYZ_DATA_CFG
627 rcall I2C_TX ; send byte 593 rcall I2C_TX ; send byte
628 movlw b'00000000' ; high pass filter = 0, +/- 2 g range 594 movlw b'00000000' ; high pass filter = 0, +/- 2 g range
629 rcall I2C_TX ; send byte 595 rcall I2C_TX ; send byte
630 bsf SSP1CON2,PEN ; stop condition 596 rcall I2C_PEN ; stop condition
631 rcall WaitMSSP ; wait for TX to complete 597 rcall I2C_SEN ; start condition
632 bsf SSP1CON2,SEN ; start condition
633 rcall WaitMSSP ; wait for TX to complete
634 movlw 0x38 ; address 598 movlw 0x38 ; address
635 rcall I2C_TX ; send byte 599 rcall I2C_TX ; send byte
636 movlw 0x2A ; CTRL_REG1 600 movlw 0x2A ; CTRL_REG1
637 rcall I2C_TX ; send byte 601 rcall I2C_TX ; send byte
638 ; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode 602 ; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode
639 movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode 603 movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode
640 rcall I2C_TX ; send byte 604 rcall I2C_TX ; send byte
641 movlw b'00000010' ; CTRL_REG2: high-res in active mode 605 movlw b'00000010' ; CTRL_REG2: high-res in active mode
642 rcall I2C_TX ; send byte 606 rcall I2C_TX ; send byte
643 bsf SSP1CON2,PEN ; stop condition 607 rcall I2C_PEN ; stop condition
644 rcall WaitMSSP ; wait for TX to complete 608
645 609 rcall I2C_SEN ; start condition
646 bsf SSP1CON2,SEN ; start condition
647 rcall WaitMSSP ; wait for TX to complete
648 movlw 0x38 ; address 610 movlw 0x38 ; address
649 rcall I2C_TX ; send byte 611 rcall I2C_TX ; send byte
650 movlw 0x2A ; CTRL_REG1 612 movlw 0x2A ; CTRL_REG1
651 rcall I2C_TX ; send byte 613 rcall I2C_TX ; send byte
652 ; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode 614 ; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode
653 movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode 615 movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode
654 rcall I2C_TX ; send byte 616 rcall I2C_TX ; send byte
655 bsf SSP1CON2,PEN ; stop condition 617 bra I2C_PEN ; stop condition
656 rcall WaitMSSP ; wait for TX to complete
657 return ; done
658 618
659 619
660 620
661 I2C_init_compass1: 621 I2C_init_compass1:
662 bsf SSP1CON2,SEN ; start condition 622 rcall I2C_SEN ; start condition
663 rcall WaitMSSP ; wait for TX to complete
664 movlw 0x3C ; address 623 movlw 0x3C ; address
665 movff WREG,i2c_error_vault+0 ; Store address
666 rcall I2C_TX ; send byte 624 rcall I2C_TX ; send byte
667 movlw 0x9F ; 1F with auto-increment (MSB=1) 625 movlw 0x9F ; 1F with auto-increment (MSB=1)
668 rcall I2C_TX ; send byte 626 rcall I2C_TX ; send byte
669 movlw b'00000000' ; CTRL0 627 movlw b'00000000' ; CTRL0
670 rcall I2C_TX ; send byte 628 rcall I2C_TX ; send byte
695 dcfsnz i2c_temp1,F ; = 7? 653 dcfsnz i2c_temp1,F ; = 7?
696 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) 654 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss)
697 rcall I2C_TX ; send byte 655 rcall I2C_TX ; send byte
698 movlw b'00000000' ; CTRL7 Continuous Mode 656 movlw b'00000000' ; CTRL7 Continuous Mode
699 rcall I2C_TX ; send byte 657 rcall I2C_TX ; send byte
700 bsf SSP1CON2,PEN ; stop condition 658 bra I2C_PEN ; stop condition
701 rcall WaitMSSP ; wait for TX to complete
702 return ; done
703 659
704 ; accelerometer initializes along with magnetic sensor 660 ; accelerometer initializes along with magnetic sensor
705 661
706 662
707 I2C_init_compass2: 663 I2C_init_compass2:
708 ; magnetic 664 ; magnetic
709 bsf SSP1CON2,SEN ; start condition 665 rcall I2C_SEN ; start condition
710 rcall WaitMSSP ; wait for TX to complete
711 movlw 0x3C ; address 666 movlw 0x3C ; address
712 movff WREG,i2c_error_vault+0 ; Store address
713 rcall I2C_TX ; send byte 667 rcall I2C_TX ; send byte
714 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) 668 movlw 0xE0 ; 0x60 with auto-increment (MSB=1)
715 rcall I2C_TX ; send byte 669 rcall I2C_TX ; send byte
716 movlw b'10000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00 670 movlw b'10000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00
717 rcall I2C_TX ; send byte 671 rcall I2C_TX ; send byte
718 movlw b'00000011' ; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR) 672 movlw b'00000011' ; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR)
719 rcall I2C_TX ; send byte 673 rcall I2C_TX ; send byte
720 movlw b'00010000' ; CFG_REG_C_M BDU=1 0x62 0x57 674 movlw b'00010000' ; CFG_REG_C_M BDU=1 0x62 0x57
721 rcall I2C_TX ; send byte 675 rcall I2C_TX ; send byte
722 bsf SSP1CON2,PEN ; stop condition 676 rcall I2C_PEN ; stop condition
723 rcall WaitMSSP ; wait for TX to complete
724 677
725 ; accelerometer 678 ; accelerometer
726 bsf SSP1CON2,SEN ; start condition 679 rcall I2C_SEN ; start condition
727 rcall WaitMSSP ; wait for TX to complete
728 movlw 0x32 ; address 680 movlw 0x32 ; address
729 movff WREG,i2c_error_vault+0 ; Store address
730 rcall I2C_TX ; send byte 681 rcall I2C_TX ; send byte
731 movlw 0x9F ; 1F with auto-increment (MSB=1) 682 movlw 0x9F ; 1F with auto-increment (MSB=1)
732 rcall I2C_TX ; send byte 683 rcall I2C_TX ; send byte
733 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) 684 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off)
734 rcall I2C_TX ; send byte 685 rcall I2C_TX ; send byte
740 rcall I2C_TX ; send byte 691 rcall I2C_TX ; send byte
741 movlw b'00001000' ; CTRL_REG4_A (BDU=0, +/-2g, HR=1) 692 movlw b'00001000' ; CTRL_REG4_A (BDU=0, +/-2g, HR=1)
742 rcall I2C_TX ; send byte 693 rcall I2C_TX ; send byte
743 ; movlw b'00000000' ; CTRL_REG5_A 694 ; movlw b'00000000' ; CTRL_REG5_A
744 ; rcall I2C_TX ; send byte 695 ; rcall I2C_TX ; send byte
745 bsf SSP1CON2,PEN ; stop condition 696 bra I2C_PEN ; stop condition
746 rcall WaitMSSP ; wait for TX to complete
747 return ; done
748 697
749 698
750 I2C_init_compass3: 699 I2C_init_compass3:
751 ; magnetic 700 ; magnetic
752 bsf SSP1CON2,SEN ; start condition 701 rcall I2C_SEN ; start condition
753 rcall WaitMSSP ; wait for TX to complete
754 movlw 0x3C ; address 702 movlw 0x3C ; address
755 movff WREG,i2c_error_vault+0 ; Store address
756 rcall I2C_TX ; send byte 703 rcall I2C_TX ; send byte
757 movlw 0xA0 ; 0x20 with auto-increment (MSB=1) 704 movlw 0xA0 ; 0x20 with auto-increment (MSB=1)
758 rcall I2C_TX ; send byte 705 rcall I2C_TX ; send byte
759 movlw b'01110000' ; CTRL_REG1_M (10Hz, X and Y in Ultra-high performance mode) 0x20 706 movlw b'01110000' ; CTRL_REG1_M (10Hz, X and Y in Ultra-high performance mode) 0x20
760 rcall I2C_TX ; send byte 707 rcall I2C_TX ; send byte
766 rcall I2C_TX ; send byte 713 rcall I2C_TX ; send byte
767 movlw b'00000000' ; CTRL_REG5_M 0x24 714 movlw b'00000000' ; CTRL_REG5_M 0x24
768 rcall I2C_TX ; send byte 715 rcall I2C_TX ; send byte
769 movlw b'00000000' ; CTRL_REG5_M 0x24 716 movlw b'00000000' ; CTRL_REG5_M 0x24
770 rcall I2C_TX ; send byte 717 rcall I2C_TX ; send byte
771 bsf SSP1CON2,PEN ; Stop condition 718 rcall I2C_PEN ; stop condition
772 rcall WaitMSSP ; wait for TX to complete
773 719
774 ;accelerometer 720 ;accelerometer
775 bsf SSP1CON2,SEN ; start condition 721 rcall I2C_SEN ; start condition
776 rcall WaitMSSP ; wait for TX to complete
777 movlw 0x3A ; address 722 movlw 0x3A ; address
778 movff WREG,i2c_error_vault+0 ; Store address
779 rcall I2C_TX ; send byte 723 rcall I2C_TX ; send byte
780 movlw 0x20 724 movlw 0x20
781 rcall I2C_TX ; send byte 725 rcall I2C_TX ; send byte
782 movlw b'10010111' ; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20 726 movlw b'10010111' ; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20
783 rcall I2C_TX ; send byte 727 rcall I2C_TX ; send byte
785 rcall I2C_TX ; send byte 729 rcall I2C_TX ; send byte
786 movlw b'00000000' ; CTRL_REG3_A 0x22 730 movlw b'00000000' ; CTRL_REG3_A 0x22
787 rcall I2C_TX ; send byte 731 rcall I2C_TX ; send byte
788 movlw b'11001100' ; CTRL_REG4_A 0x23 732 movlw b'11001100' ; CTRL_REG4_A 0x23
789 rcall I2C_TX ; send byte 733 rcall I2C_TX ; send byte
790 bsf SSP1CON2,PEN ; stop condition 734 bra I2C_PEN ; stop condition
791 rcall WaitMSSP ; wait for TX to complete 735
792 return ; done 736
793 737
794 ;-----------------------------------------------------------------------------
795 ; Helper Function - send 1 Byte, wait for end of transmission and check ackn
796 ;
797 I2C_TX:
798 movwf SSP1BUF ; put byte to be sent into TX buffer
799 rcall WaitMSSP ; wait for TX to complete
800 bra I2C_Check_ACK ; check for acknowledge by receiver and return
801
802 ;----------------------------------------------------------------------------- 738 ;-----------------------------------------------------------------------------
803 ; Deactivate Compass / Accelerometer 739 ; Deactivate Compass / Accelerometer
804 ; 740 ;
805 global I2C_sleep_compass 741 global I2C_sleep_compass
806 I2C_sleep_compass: 742 I2C_sleep_compass:
816 ;bra I2C_sleep_compass0 ; NO - must be compass 0 then 752 ;bra I2C_sleep_compass0 ; NO - must be compass 0 then
817 753
818 754
819 I2C_sleep_compass0: 755 I2C_sleep_compass0:
820 ; magnetic 756 ; magnetic
821 bsf SSP1CON2,SEN ; start condition 757 rcall I2C_SEN ; start condition
822 rcall WaitMSSP ; wait for TX to complete
823 movlw 0x3C ; address 758 movlw 0x3C ; address
824 movff WREG,i2c_error_vault+0 ; Store address
825 rcall I2C_TX ; send byte 759 rcall I2C_TX ; send byte
826 movlw 0x00 ; ?? 760 movlw 0x00 ; ??
827 rcall I2C_TX ; send byte 761 rcall I2C_TX ; send byte
828 movlw b'01101000' ; ConfigA 762 movlw b'01101000' ; ConfigA
829 rcall I2C_TX ; send byte 763 rcall I2C_TX ; send byte
830 movlw b'00100000' ; ConfigB 764 movlw b'00100000' ; ConfigB
831 rcall I2C_TX ; send byte 765 rcall I2C_TX ; send byte
832 movlw b'00000010' ; idle mode 766 movlw b'00000010' ; idle mode
833 rcall I2C_TX ; send byte 767 rcall I2C_TX ; send byte
834 bsf SSP1CON2,PEN ; stop condition 768 rcall I2C_PEN ; stop condition
835 rcall WaitMSSP ; wait for TX to complete
836 769
837 I2C_sleep_accelerometer0: 770 I2C_sleep_accelerometer0:
838 ; accelerometer 771 ; accelerometer
839 bsf SSP1CON2,SEN ; start condition 772 rcall I2C_SEN ; start condition
840 rcall WaitMSSP ; wait for TX to complete
841 movlw 0x38 ; address 773 movlw 0x38 ; address
842 movff WREG,i2c_error_vault+0 ; Store address
843 rcall I2C_TX ; send byte 774 rcall I2C_TX ; send byte
844 movlw 0x2A ; CTRL_REG1 775 movlw 0x2A ; CTRL_REG1
845 rcall I2C_TX ; send byte 776 rcall I2C_TX ; send byte
846 movlw b'00000000' ; standby mode 777 movlw b'00000000' ; standby mode
847 rcall I2C_TX ; send byte 778 rcall I2C_TX ; send byte
848 bsf SSP1CON2,PEN ; stop condition 779 bra I2C_PEN ; stop condition
849 rcall WaitMSSP ; wait for TX to complete
850 return ; done
851 780
852 781
853 I2C_sleep_compass1: 782 I2C_sleep_compass1:
854 bsf SSP1CON2,SEN ; start condition 783 rcall I2C_SEN ; start condition
855 rcall WaitMSSP ; wait for TX to complete
856 movlw 0x3C ; address 784 movlw 0x3C ; address
857 movff WREG,i2c_error_vault+0 ; Store address
858 rcall I2C_TX ; send byte 785 rcall I2C_TX ; send byte
859 movlw 0x20 ; CTRL_REG1 786 movlw 0x20 ; CTRL_REG1
860 rcall I2C_TX ; send byte 787 rcall I2C_TX ; send byte
861 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor power-down mode 788 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor power-down mode
862 rcall I2C_TX ; send byte 789 rcall I2C_TX ; send byte
863 bsf SSP1CON2,PEN ; stop condition 790 rcall I2C_PEN ; stop condition
864 rcall WaitMSSP ; wait for TX to complete 791 rcall I2C_SEN ; start condition
865 bsf SSP1CON2,SEN ; start condition
866 rcall WaitMSSP ; wait for TX to complete
867 movlw 0x3C ; address 792 movlw 0x3C ; address
868 rcall I2C_TX ; send byte 793 rcall I2C_TX ; send byte
869 movlw 0x26 ; CTRL_REG7 794 movlw 0x26 ; CTRL_REG7
870 rcall I2C_TX ; send byte 795 rcall I2C_TX ; send byte
871 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode 796 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode
872 rcall I2C_TX ; send byte 797 rcall I2C_TX ; send byte
873 bsf SSP1CON2,PEN ; stop condition 798 bra I2C_PEN ; stop condition
874 rcall WaitMSSP ; wait for TX to complete
875 return ; done
876 799
877 ; accelerometer sleeps with magnetic sensor 800 ; accelerometer sleeps with magnetic sensor
878 801
879 802
880 I2C_sleep_compass2: 803 I2C_sleep_compass2:
881 ; magnetic 804 ; magnetic
882 bsf SSP1CON2,SEN ; start condition 805 rcall I2C_SEN ; start condition
883 rcall WaitMSSP ; wait for TX to complete
884 movlw 0x3C ; address 806 movlw 0x3C ; address
885 movff WREG,i2c_error_vault+0 ; Store address
886 rcall I2C_TX ; send byte 807 rcall I2C_TX ; send byte
887 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) 808 movlw 0xE0 ; 0x60 with auto-increment (MSB=1)
888 rcall I2C_TX ; send byte 809 rcall I2C_TX ; send byte
889 movlw b'00000011' ; CFG_REG_A_M 0x60 (idle mode)) 810 movlw b'00000011' ; CFG_REG_A_M 0x60 (idle mode))
890 rcall I2C_TX ; send byte 811 rcall I2C_TX ; send byte
892 rcall I2C_TX ; send byte 813 rcall I2C_TX ; send byte
893 movlw b'01010001' ; CFG_REG_C_M 0x62 814 movlw b'01010001' ; CFG_REG_C_M 0x62
894 rcall I2C_TX ; send byte 815 rcall I2C_TX ; send byte
895 movlw b'00000000' ; INT_CTRL_REG_M 0x63 816 movlw b'00000000' ; INT_CTRL_REG_M 0x63
896 rcall I2C_TX ; send byte 817 rcall I2C_TX ; send byte
897 bsf SSP1CON2,PEN ; stop condition 818 rcall I2C_PEN ; stop condition
898 rcall WaitMSSP ; wait for TX to complete
899 819
900 ; accelerometer 820 ; accelerometer
901 bsf SSP1CON2,SEN ; start condition 821 rcall I2C_SEN ; start condition
902 rcall WaitMSSP ; wait for TX to complete
903 movlw 0x32 ; address 822 movlw 0x32 ; address
904 movff WREG,i2c_error_vault+0 ; Store address
905 rcall I2C_TX ; send byte 823 rcall I2C_TX ; send byte
906 movlw 0x9F ; 1F with auto-increment (MSB=1) 824 movlw 0x9F ; 1F with auto-increment (MSB=1)
907 rcall I2C_TX ; send byte 825 rcall I2C_TX ; send byte
908 movlw b'00000000' ; TEMP_CFG_REG_A 0x1F (temp sensor off) 826 movlw b'00000000' ; TEMP_CFG_REG_A 0x1F (temp sensor off)
909 rcall I2C_TX ; send byte 827 rcall I2C_TX ; send byte
910 movlw b'00000000' ; CTRL_REG1_A 0x20 (all off) 828 movlw b'00000000' ; CTRL_REG1_A 0x20 (all off)
911 rcall I2C_TX ; send byte 829 rcall I2C_TX ; send byte
912 bsf SSP1CON2,PEN ; stop condition 830 bra I2C_PEN ; stop condition
913 rcall WaitMSSP ; wait for TX to complete
914 return ; done
915 831
916 832
917 I2C_sleep_compass3: 833 I2C_sleep_compass3:
918 ; magnetic 834 ; magnetic
919 bsf SSP1CON2,SEN ; start condition 835 rcall I2C_SEN ; start condition
836 movlw 0x3C ; address
837 rcall I2C_TX ; send byte
838 movlw 0xA2 ; 0x22 with auto-increment (MSB=1)
839 rcall I2C_TX ; send byte
840 movlw b'01000010' ; CTRL_REG3_M (power-down) 0x22
841 rcall I2C_TX ; send byte
842 rcall I2C_PEN ; stop condition
843
844 ; accelerometer
845 rcall I2C_SEN ; start condition
846 movlw 0x3A ; address
847 rcall I2C_TX ; send byte
848 movlw 0x20
849 rcall I2C_TX ; send byte
850 movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20
851 rcall I2C_TX ; send byte
852 bra I2C_PEN ; stop condition
853
854
855 ;-----------------------------------------------------------------------------
856 ; Helper Function - receive 1 Byte with Not-Acknowledge
857 ;
858 I2C_OneByteRX_NACK:
859 rcall I2C_RCEN ; enable receive mode
860 bsf SSP1CON2,ACKDT ; set ACKDT flag
861 rcall I2C_ACKEN ; send master acknowledge
862 bcf SSP1CON2,ACKDT ; reset ACKDT flag
863 return
864
865
866 ;-----------------------------------------------------------------------------
867 ; Helper Function - receive 1 Byte with Acknowledge
868 ;
869 I2C_OneByteRX:
870 rcall I2C_RCEN ; enable receive mode
871 bra I2C_ACKEN ; send master acknowledge
872
873 ;-----------------------------------------------------------------------------
874 ; Helper Function - send 1 Byte, wait for end of transmission and check ackn
875 ; add WREG to checksum byte first
876 I2C_TX_CHKSUM:
877 addwf sub_a+0,F ; add to checksum
878 ; bra I2C_TX
879 ;-----------------------------------------------------------------------------
880 ; Helper Function - send 1 Byte, wait for end of transmission and check ackn
881 ;
882 I2C_TX:
883 movwf SSP1BUF ; put byte to be sent into TX buffer
884 btfss i2c_error_flag_lock ; vault in use already?
885 movff WREG,i2c_error_vault+0 ; NO, Store address
920 rcall WaitMSSP ; wait for TX to complete 886 rcall WaitMSSP ; wait for TX to complete
921 movlw 0x3C ; address 887 bra I2C_Check_ACK ; check for acknowledge by receiver and return
922 movff WREG,i2c_error_vault+0 ; Store address 888
923 rcall I2C_TX ; send byte 889
924 movlw 0xA2 ; 0x22 with auto-increment (MSB=1) 890 ;-----------------------------------------------------------------------------
925 rcall I2C_TX ; send byte 891 ; Helper Function - I2C Start Condition
926 movlw b'01000010' ; CTRL_REG3_M (power-down) 0x22 892 ;
927 rcall I2C_TX ; send byte 893 I2C_SEN:
928 bsf SSP1CON2,PEN ; stop condition 894 bsf SSP1CON2,SEN ; start condition
929 rcall WaitMSSP ; wait for TX to complete 895 bra WaitMSSP ; wait for TX to complete (And return)
930 896
931 ; accelerometer 897 ;-----------------------------------------------------------------------------
932 bsf SSP1CON2,SEN ; start condition 898 ; Helper Function - I2C Repeated Start Condition
933 rcall WaitMSSP ; wait for TX to complete 899 ;
934 movlw 0x3A ; address 900 I2C_RSEN:
935 movff WREG,i2c_error_vault+0 ; Store address 901 bsf SSP1CON2,RSEN ; repeated start condition
936 rcall I2C_TX ; send byte 902 bra WaitMSSP ; wait for TX to complete (And return)
937 movlw 0x20 903
938 rcall I2C_TX ; send byte 904
939 movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20 905 ;-----------------------------------------------------------------------------
940 rcall I2C_TX ; send byte 906 ; Helper Function - I2C Stop Condition
941 bsf SSP1CON2,PEN ; stop condition 907 ;
942 rcall WaitMSSP ; wait for TX to complete 908 I2C_PEN:
943 return ; done 909 bsf SSP1CON2,PEN ; stop condition
944 910 rcall WaitMSSP ; wait for TX to complete (And return)
945 911 I2C_WAIT_100US:
912 ; add ~100µs bus free time (min. 66µs recommended for LTC2959)
913 ; Remark: not exact: 122µs +/- 30.5 µs + worst case ISR latency
914 setf TMR5H ; initialize timer 5, high byte first
915 movlw .255-.4 ; 4 x 31.5 µs = 126µs, min: 94,5µs
916 movwf TMR5L ; initialize timer 5, low byte thereafter
917 bcf PIR5,TMR5IF ; clear timer 5 overrun flag
918 I2C_PEN_Loop:
919 btfss PIR5,TMR5IF ; did timer 5 overrun?
920 bra I2C_PEN_Loop ; NO - repeat inner loop
921 return
922
923 ;-----------------------------------------------------------------------------
924 ; Helper Function - Master Acknowledge
925 ;
926 I2C_ACKEN:
927 bsf SSP1CON2,ACKEN ; master acknowledge
928 bra WaitMSSP ; wait for TX to complete (And return)
929
930 ;-----------------------------------------------------------------------------
931 ; Helper Function - Enable reeive mode
932 ;
933 I2C_RCEN:
934 bsf SSP1CON2,RCEN ; enable receive mode
935 bra WaitMSSP ; wait for TX to complete (And return)
936
946 ;----------------------------------------------------------------------------- 937 ;-----------------------------------------------------------------------------
947 ; Helper Function - wait for TX to complete 938 ; Helper Function - wait for TX to complete
948 ; 939 ;
949 WaitMSSP: 940 WaitMSSP:
950 movff SSP1BUF,i2c_error_vault+1 941 btfss i2c_error_flag_lock ; vault in use already?
942 movff SSP1BUF,i2c_error_vault+1 ; NO, store value
943 btfss i2c_error_flag_lock ; vault in use already?
944 movff SSP1CON2,i2c_error_vault+2 ; NO, store value
951 clrf i2c_temp1 ; wait for max 256 loops 945 clrf i2c_temp1 ; wait for max 256 loops
952 WaitMSSP_loop: 946 WaitMSSP_loop:
953 decfsz i2c_temp1,F ; decrement loop counter, timeout? 947 decfsz i2c_temp1,F ; decrement loop counter, timeout?
954 bra WaitMSSP2 ; NO 948 bra WaitMSSP2 ; NO
955 bra I2CFail ; YES 949 bra I2CFail ; YES
963 ;----------------------------------------------------------------------------- 957 ;-----------------------------------------------------------------------------
964 ; Helper Function - Master NOT acknowledge and Stop 958 ; Helper Function - Master NOT acknowledge and Stop
965 ; 959 ;
966 I2C_MasterNotAckStop: 960 I2C_MasterNotAckStop:
967 bsf SSP1CON2,ACKDT ; set ACKDT flag 961 bsf SSP1CON2,ACKDT ; set ACKDT flag
968 bsf SSP1CON2,ACKEN ; master NOT acknowledge 962 rcall I2C_ACKEN ; send master NOT acknowledge
969 rcall WaitMSSP ; wait for TX to complete
970 bcf SSP1CON2,ACKDT ; reset ACKDT flag 963 bcf SSP1CON2,ACKDT ; reset ACKDT flag
971 964
972 bsf SSP1CON2,PEN ; stop condition 965 bra I2C_PEN ; stop condition
973 bra WaitMSSP ; wait for TX to complete
974 966
975 ;----------------------------------------------------------------------------- 967 ;-----------------------------------------------------------------------------
976 ; Helper Function - check for Acknowledge by Receiver 968 ; Helper Function - check for Acknowledge by Receiver
977 ; 969 ;
978 I2C_Check_ACK: 970 I2C_Check_ACK:
987 I2CFail: 979 I2CFail:
988 bsf active_reset_ostc_rx ; reset RX circuitry (which may be the cause for the hang up) 980 bsf active_reset_ostc_rx ; reset RX circuitry (which may be the cause for the hang up)
989 rcall I2CReset ; reset I2C 981 rcall I2CReset ; reset I2C
990 bcf PIR1,SSP1IF ; clear TX completion flag 982 bcf PIR1,SSP1IF ; clear TX completion flag
991 bsf i2c_error_flag ; set error flag 983 bsf i2c_error_flag ; set error flag
984 bsf i2c_error_flag_lock ; lock the error vault
992 bcf active_reset_ostc_rx ; release reset from RX circuitry 985 bcf active_reset_ostc_rx ; release reset from RX circuitry
993 ; bcf i2c_busy_temperature 986 ; bcf i2c_busy_temperature
994 ; bcf i2c_busy_pressure 987 ; bcf i2c_busy_pressure
995 return ; done 988 return ; done
996 989
998 ;----------------------------------------------------------------------------- 991 ;-----------------------------------------------------------------------------
999 ; Helper Function - Reset I2C Module 992 ; Helper Function - Reset I2C Module
1000 ; 993 ;
1001 ; recover in case something went wrong, i.g. slave holds SDA low 994 ; recover in case something went wrong, i.g. slave holds SDA low
1002 ; 995 ;
996 global I2CReset
1003 I2CReset: 997 I2CReset:
1004 clrf SSP1CON1 ; reset entire module 998 clrf SSP1CON1 ; reset entire module
1005 clrf SSP1CON2 ; ... 999 clrf SSP1CON2 ; ...
1006 clrf SSP1STAT ; ... 1000 clrf SSP1STAT ; ...
1007 bcf TRISC,3 ; SCL as OUTPUT 1001 bcf TRISC,3 ; SCL as OUTPUT
1026 decfsz i2c_temp1,F ; - clock counter, all cycles done? 1020 decfsz i2c_temp1,F ; - clock counter, all cycles done?
1027 bra I2CReset_1 ; NO - loop 1021 bra I2CReset_1 ; NO - loop
1028 I2CReset_2: 1022 I2CReset_2:
1029 bsf TRISC,3 ; SCL as input 1023 bsf TRISC,3 ; SCL as input
1030 clrf SSP1CON1 ; setup I2C mode 1024 clrf SSP1CON1 ; setup I2C mode
1031 WAITMS d'10' ; wait 10 ms (reset-timeout for I2C devices) 1025 rcall I2C_WAIT_100US ; ISR-Safe 100µs wait
1032 movlw b'00000000' ; enable slew rate control 1026 movlw b'00000000' ; enable slew rate control
1033 movwf SSP1STAT ; ... 1027 movwf SSP1STAT ; ...
1034 movlw b'00101000' ; configure I2C module 1028 movlw b'00101000' ; configure I2C module
1035 movwf SSP1CON1 ; ... 1029 movwf SSP1CON1 ; ...
1036 movlw b'00000000' ; ... 1030 movlw b'00000000' ; ...
1037 movwf SSP1CON2 ; ... 1031 movwf SSP1CON2 ; ...
1038 movlw i2c_speed_value 1032 movlw i2c_speed_value
1039 movwf SSP1ADD ; ... 1033 movwf SSP1ADD ; ...
1040 return ; done 1034 rcall I2C_WAIT_100US ; ISR-Safe 100µs wait
1035 movlw .1
1036 addwf i2c_error_counter+0
1037 movlw .0
1038 addwfc i2c_error_counter+1 ; +1 on the error counter
1039 btfss press_sensor_type ; =1: pressure sensor MS5837, =0: Pressure sensor MS5541
1040 return ; MS5541, Done.
1041 ; reset the sensor
1042 rcall I2C_SEN ; start condition
1043 movlw 0xEC ; address byte + write bit
1044 rcall I2C_TX ; send byte
1045 movlw 0x1E
1046 rcall I2C_TX ; send byte
1047 rcall I2C_PEN ; stop condition
1048 WAITMS .5 ; 2.8ms according to datasheet
1049 return ; done
1041 1050
1042 1051
1043 ;----------------------------------------------------------------------------- 1052 ;-----------------------------------------------------------------------------
1044 ; Helper Function - Initialize Gauge IC again after an UVLO Event 1053 ; Helper Function - Initialize Gauge IC again after an UVLO Event
1045 ; 1054 ;
1046 lt2942_init_again: 1055 battery_gauge_init_again:
1056 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1057 return
1047 rcall I2CReset 1058 rcall I2CReset
1048 movlw 0x02 ; point to accumulated charge registers 1059 movlw 0x02 ; point to accumulated charge registers
1049 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1060 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1050 movff battery_accumulated_charge+1,SSP1BUF ; data byte 1061 movff battery_accumulated_charge+1,SSP1BUF ; data byte
1051 rcall WaitMSSP ; wait for TX to complete 1062 rcall WaitMSSP ; wait for TX to complete
1052 rcall I2C_Check_ACK ; check for acknowledge by receiver 1063 rcall I2C_Check_ACK ; check for acknowledge by receiver
1053 movff battery_accumulated_charge+0,SSP1BUF ; data byte 1064 movff battery_accumulated_charge+0,SSP1BUF ; data byte
1054 rcall WaitMSSP ; wait for TX to complete 1065 rcall WaitMSSP ; wait for TX to complete
1055 rcall I2C_Check_ACK ; check for acknowledge by receiver 1066 rcall I2C_Check_ACK ; check for acknowledge by receiver
1056 bsf SSP1CON2,PEN ; stop condition 1067 rcall I2C_PEN ; stop condition
1057 rcall WaitMSSP ; wait for TX to complete
1058 MOVII battery_accumulated_charge,sub_a ; copy result to sub_a 1068 MOVII battery_accumulated_charge,sub_a ; copy result to sub_a
1059 ;bra lt2942_init ; and initialize again... 1069 ;bra battery_gauge_init ; and initialize again...
1060 1070
1061 1071
1062 ;----------------------------------------------------------------------------- 1072 ;-----------------------------------------------------------------------------
1063 ; Initialize Gauge IC 1073 ; Initialize Gauge IC
1064 ; 1074 ;
1065 global lt2942_init 1075 global battery_gauge_init
1066 lt2942_init: 1076 battery_gauge_init:
1067 movlw 0x01 ; point to control reg B 1077 movlw 0x01 ; point to control reg B / ADC Control
1068 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1078 rcall I2C_TX_GAUGE ; send byte to the gauge IC
1069 movlw b'11111000' ; automatic conversion every two seconds 1079 movlw b'11111000' ; automatic conversion every two seconds (LT2942)
1070 movwf SSP1BUF ; data byte 1080 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1071 rcall WaitMSSP ; wait for TX to complete 1081 movlw b'00111000' ; ADC Mode to "Smart Sleep" (converts V, I, T every 52 seconds (tolerance < ±5%)) (LTC2959)
1072 rcall I2C_Check_ACK ; check for acknowledge by receiver 1082 rcall I2C_TX ; send byte
1073 bsf SSP1CON2,PEN ; stop condition 1083 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1074 rcall WaitMSSP ; wait for TX to complete 1084 movlw b'01010000' ; 20µV deadband
1075 return ; done 1085 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1076 1086 rcall I2C_TX ; send one byte more for the LTC2959
1077 ;----------------------------------------------------------------------------- 1087 bra I2C_PEN ; stop condition
1078 ; Sleep Gauge IC
1079 ;
1080 global lt2942_sleep
1081 lt2942_sleep:
1082 movlw 0x01 ; point to control reg B
1083 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1084 movlw b'00111000' ; sleep
1085 movwf SSP1BUF ; data byte
1086 rcall WaitMSSP ; wait for TX to complete
1087 rcall I2C_Check_ACK ; check for acknowledge by receiver
1088 bsf SSP1CON2,PEN ; stop condition
1089 rcall WaitMSSP ; wait for TX to complete
1090 return ; done
1091 1088
1092 ;----------------------------------------------------------------------------- 1089 ;-----------------------------------------------------------------------------
1093 ; Read Gauge IC - Status Register 1090 ; Read Gauge IC - Status Register
1094 ; 1091 ;
1095 global lt2942_get_status 1092 global lt2942_get_status
1096 lt2942_get_status: 1093 lt2942_get_status:
1097 bcf battery_gauge_available ; clear flag 1094 bcf battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1098 movlw 0x00 ; point to status register 1095 bcf battery_gauge_available ; clear flag on default
1099 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1096
1100 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC 1097 ; try LTC2942
1101 1098 rcall I2C_SEN ; start condition
1102 bsf SSP1CON2,ACKDT ; set ACKDT flag 1099 movlw 0xC8 ; address byte + Write bit
1103 bsf SSP1CON2,ACKEN ; master NOT acknowledge 1100 movwf SSP1BUF ; put byte to be sent into TX buffer
1104 rcall WaitMSSP ; wait for TX to complete 1101 rcall WaitMSSP ; wait for TX to complete
1105 bcf SSP1CON2,ACKDT ; reset ACKDT flag 1102 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
1106 1103 btfss SSP1CON2,ACKSTAT ; ACK received from slave?
1107 movff SSP1BUF,WREG ; copy received byte to WREG 1104 bsf battery_gauge_available ; YES - set flag
1108 btfss WREG,7 ; 2942 found? 1105 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1109 bsf battery_gauge_available ; YES - set flag 1106 btfsc battery_gauge_available ; found?
1110 bsf SSP1CON2,PEN ; stop condition 1107 return ; YES - done
1108
1109 ; try LTC2959
1110 rcall I2C_SEN ; start condition
1111 movlw 0xC6 ; address byte + Write bit
1112 movwf SSP1BUF ; put byte to be sent into TX buffer
1111 rcall WaitMSSP ; wait for TX to complete 1113 rcall WaitMSSP ; wait for TX to complete
1112 return ; done 1114 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
1113 1115 btfss SSP1CON2,ACKSTAT ; ACK received from slave?
1116 bsf battery_gauge_available ; YES - set flag
1117 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1118 btfsc battery_gauge_available ; found?
1119 bsf battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1120 return ; NO, return
1114 1121
1115 ;----------------------------------------------------------------------------- 1122 ;-----------------------------------------------------------------------------
1116 ; Read Gauge IC - Voltage 1123 ; Read Gauge IC - Voltage
1117 ; 1124 ;
1118 global lt2942_get_voltage 1125 global lt2942_get_voltage
1119 lt2942_get_voltage: 1126 lt2942_get_voltage:
1127
1128 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1129 bra LTC2959_get_voltage ; use new IC
1130
1120 movlw 0x08 ; point to voltage registers 1131 movlw 0x08 ; point to voltage registers
1121 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1132 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1122 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC 1133 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC
1123 bsf SSP1CON2,ACKEN ; master acknowledge 1134 rcall I2C_ACKEN ; send master acknowledge
1124 rcall WaitMSSP ; wait for TX to complete
1125 movff SSP1BUF,xA+1 ; copy received byte to xA+1 1135 movff SSP1BUF,xA+1 ; copy received byte to xA+1
1126 bsf SSP1CON2,RCEN ; enable receive mode 1136 rcall I2C_RCEN ; enable receive mode
1127 rcall WaitMSSP ; wait for TX to complete
1128 movff SSP1BUF,xA+0 ; copy received byte to xA+0 1137 movff SSP1BUF,xA+0 ; copy received byte to xA+0
1129 1138
1130 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1139 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1131 1140
1132 ; convert voltage from raw value to Volt 1141 ; convert voltage from raw value to Volt
1133 MOVLI .6000,xB ; load conversion multiplicand into xB 1142 MOVLI .6000,xB ; load conversion multiplicand into xB
1134 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand 1143 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand
1135 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % 1144 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 %
1136 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 1145 movff xC+2,xC+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
1137 movff xC+3,batt_voltage+1 ; ... 1146 movff xC+3,xC+1 ; use xC+0 and xC+1 as temp
1138 1147
1139 tstfsz batt_voltage+1 ; < 256 mV ? 1148 movlw .4 ; battery voltage < 4*256mV (1.024)?
1140 return ; NO - done 1149 cpfslt xC+1 ; < 1024 mV ?
1141 bra lt2942_init_again ; YES - initialize gauge and return 1150 bra lt2942_get_voltage_check_high ; NO - Continue checking
1151 bra battery_gauge_init_again ; YES - initialize gauge and return (and leave batt_voltage:2 untouched)
1152
1153 lt2942_get_voltage_check_high:
1154 movlw .17 ; battery voltage >= 17*256mV (4.352V)?
1155 cpfslt xC+1 ; - ... ?
1156 bra battery_gauge_init_again ; YES - initialize gauge and return (and leave batt_voltage:2 untouched)
1157 ; NO - done
1158 movff xC+0, batt_voltage+0
1159 movff xC+1, batt_voltage+1
1160 bra lt2942_get_accumulated_charge ; - read coulomb counter (And return)
1161
1162 LTC2959_get_voltage:
1163 movlw 0x0F ; point to voltage registers
1164 rcall I2C_TX_GAUGE ; send byte to the gauge IC
1165 rcall I2C_RX_GAUGE ; receive byte from the Gauge IC
1166 rcall I2C_ACKEN ; send master acknowledge
1167 movff SSP1BUF,xA+1 ; copy received byte to xA+1
1168 rcall I2C_RCEN ; enable receive mode
1169 movff SSP1BUF,xA+0 ; copy received byte to xA+0
1170
1171 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1172
1173 ; convert voltage from raw value to mV
1174 MOVLI .62600,xB ; load conversion multiplicand into xB
1175 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand
1176 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 %
1177 ;movff xC+2,xC+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
1178 ;movff xC+3,xC+1 ; use xC+0 and xC+1 as temp
1179
1180 movff xC+2, batt_voltage+0
1181 movff xC+3, batt_voltage+1
1182 rcall lt2942_get_accumulated_charge ; - read coulomb counter (And return)
1183
1184 return ; done
1142 1185
1143 1186
1144 ;----------------------------------------------------------------------------- 1187 ;-----------------------------------------------------------------------------
1145 ; Read Gauge IC - Temperature 1188 ; Read Gauge IC - Temperature
1146 ; 1189 ;
1147 global lt2942_get_temperature 1190 global lt2942_get_temperature
1148 lt2942_get_temperature: ; read battery temperature 1191 lt2942_get_temperature: ; read battery temperature
1192 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1193 bra LTC2959_get_temperature
1194
1149 movlw 0x0C ; point to temperature register 1195 movlw 0x0C ; point to temperature register
1150 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1196 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1151 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC 1197 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC
1152 bsf SSP1CON2,ACKEN ; master acknowledge 1198 rcall I2C_ACKEN ; send master acknowledge
1153 rcall WaitMSSP ; wait for TX to complete
1154 movff SSP1BUF,xA+1 ; store raw temperature, high byte 1199 movff SSP1BUF,xA+1 ; store raw temperature, high byte
1155 bsf SSP1CON2,RCEN ; enable receive mode 1200 rcall I2C_RCEN ; enable receive mode
1156 rcall WaitMSSP ; wait for TX to complete
1157 movff SSP1BUF,xA+0 ; store raw temperature, low byte 1201 movff SSP1BUF,xA+0 ; store raw temperature, low byte
1158 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1202 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1159 1203
1160 ; convert temperature from raw value to Kelvin 1204 ; convert temperature from raw value to Kelvin in 0.1K
1161 MOVLI .6000,xB ; load conversion multiplicand into xB 1205 MOVLI .6000,xB ; load conversion multiplicand into xB
1162 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand 1206 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand
1163 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % 1207 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 %
1164 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 1208 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
1165 movff xC+3,battery_temperature+1 ; ... 1209 movff xC+3,battery_temperature+1 ; ...
1166 1210
1211 lt2942_get_temperature_common:
1167 ; check if battery is being charged right now 1212 ; check if battery is being charged right now
1168 btfss cc_active ; in CC charging mode? 1213 btfss cc_active ; in CC charging mode?
1169 return ; NO - not charging, done 1214 return ; NO - not charging, done
1170 1215
1171 ; ignore false readings (>125°C) 1216 ; ignore false readings (>125°C)
1187 return 1232 return
1188 ; YES - too hot, disable charging circuitry 1233 ; YES - too hot, disable charging circuitry
1189 bsf charge_disable ; - set charging-inhibit signal 1234 bsf charge_disable ; - set charging-inhibit signal
1190 bcf charge_enable ; - activate charging-inhibit signal 1235 bcf charge_enable ; - activate charging-inhibit signal
1191 bsf battery_overtemp ; - flag that the battery charging over-temperature protection has tripped 1236 bsf battery_overtemp ; - flag that the battery charging over-temperature protection has tripped
1192 return ; - done 1237 return ; - done
1193 1238
1239 LTC2959_get_temperature:
1240 return
1241
1194 1242
1195 ;----------------------------------------------------------------------------- 1243 ;-----------------------------------------------------------------------------
1196 ; Read Gauge IC - Read State of Charge 1244 ; Read Gauge IC - Read State of Charge
1197 ; 1245 ;
1198 global lt2942_get_accumulated_charge
1199 lt2942_get_accumulated_charge: ; read accumulated charge and compute percent 1246 lt2942_get_accumulated_charge: ; read accumulated charge and compute percent
1247 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LTC2942
1248 bra LTC2959_get_accumulated_charge
1249
1250 ; old LTC2942
1200 movlw 0x00 ; point to status register 1251 movlw 0x00 ; point to status register
1201 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1252 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1202 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC 1253 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC
1203 bsf SSP1CON2,ACKEN ; master acknowledge 1254 rcall I2C_ACKEN ; send master acknowledge
1204 rcall WaitMSSP ; wait for TX to complete
1205 movff SSP1BUF,gauge_status_byte ; copy received byte to gauge_status_byte 1255 movff SSP1BUF,gauge_status_byte ; copy received byte to gauge_status_byte
1206 1256
1207 bsf SSP1CON2,RCEN ; enable receive mode 1257 rcall I2C_RCEN ; enable receive mode
1208 rcall WaitMSSP ; wait for TX to complete ; dummy read (control byte) 1258 movf SSP1BUF,W ; dump to WREG (Control)
1209 movf SSP1BUF,W ; dump to WREG 1259 rcall I2C_ACKEN ; send master acknowledge
1210 bsf SSP1CON2,ACKEN ; master acknowledge 1260
1211 rcall WaitMSSP ; wait for TX to complete 1261 rcall I2C_RCEN ; enable receive mode
1212
1213 bsf SSP1CON2,RCEN ; enable receive mode
1214 rcall WaitMSSP ; wait for TX to complete
1215 movff SSP1BUF,sub_a+1 ; copy received byte to sub_a+1 1262 movff SSP1BUF,sub_a+1 ; copy received byte to sub_a+1
1216 bsf SSP1CON2,ACKEN ; master acknowledge 1263 rcall I2C_ACKEN ; send master acknowledge
1217 rcall WaitMSSP ; wait for TX to complete 1264
1218 1265 rcall I2C_RCEN ; enable receive mode
1219 bsf SSP1CON2,RCEN ; enable receive mode
1220 rcall WaitMSSP ; wait for TX to complete
1221 movff SSP1BUF,sub_a+0 ; copy received byte to sub_a+0 1266 movff SSP1BUF,sub_a+0 ; copy received byte to sub_a+0
1222 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1267 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1223 1268
1269 lt2942_get_accumulated_charge2:
1224 btfsc gauge_status_byte,0 ; UVLO event ? 1270 btfsc gauge_status_byte,0 ; UVLO event ?
1225 rcall lt2942_init_again ; YES - do an re-initialization 1271 rcall battery_gauge_init_again ; YES - do an re-initialization
1226 MOVII sub_a,battery_accumulated_charge ; save raw value 1272 MOVII sub_a,battery_accumulated_charge ; save raw value
1227 1273 ; Compute batt_percent = (charge - battery_offset) / capacity_xxxxxx
1228 ; Compute batt_percent = (charge - battery_offset) / 365
1229 MOVII battery_offset,sub_b ; get battery offset 1274 MOVII battery_offset,sub_b ; get battery offset
1230 call subU16 ; sub_c = sub_a - sub_b (with signed values) 1275 call subU16 ; sub_c = sub_a - sub_b (with signed values)
1231 clrf batt_percent ; default batt_percent to zero 1276 clrf batt_percent ; default batt_percent to zero
1232 btfsc neg_flag ; result negative? 1277 btfsc neg_flag ; result negative?
1233 bra lt2942_set_to_zero_percent ; YES - keep LT2942 at zero percent and return 1278 bra lt2942_set_to_zero_percent ; YES - keep LT2942 at zero percent and return
1238 call div16x16 ; xC = xA / xB with xA as remainder 1283 call div16x16 ; xC = xA / xB with xA as remainder
1239 movff xC+0,batt_percent ; result is battery percentage 1284 movff xC+0,batt_percent ; result is battery percentage
1240 movlw .100 ; max. value is 100 % 1285 movlw .100 ; max. value is 100 %
1241 cpfslt batt_percent ; batt_percent < 100 % ? 1286 cpfslt batt_percent ; batt_percent < 100 % ?
1242 movwf batt_percent ; NO - limit to 100 % 1287 movwf batt_percent ; NO - limit to 100 %
1243 movlw .95 ; < 95 % 1288 movlw battery_cycle_counter_unlock
1244 cpfsgt batt_percent 1289 cpfsgt batt_percent ; < threshold ?
1245 bcf lock_cycle_counter ; Yes, unlock cycle counter 1290 bcf lock_cycle_counter ; Yes, unlock cycle counter
1246 return ; done 1291 return ; done
1247 1292
1293 LTC2959_get_accumulated_charge:
1294 movlw 0x00 ; point to status register
1295 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1296 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC
1297 rcall I2C_ACKEN ; send master acknowledge
1298 movff SSP1BUF,gauge_status_byte ; copy received byte to gauge_status_byte
1299
1300 rcall I2C_RCEN ; enable receive mode
1301 movf SSP1BUF,W ; dump to WREG (ADC Control)
1302 rcall I2C_ACKEN ; send master acknowledge
1303
1304 rcall I2C_RCEN ; enable receive mode
1305 movf SSP1BUF,W ; dump to WREG (Coulumb Counter Control)
1306 rcall I2C_ACKEN ; send master acknowledge
1307
1308 rcall I2C_RCEN ; enable receive mode
1309 movff SSP1BUF,xC+3 ; copy received byte to xC+3
1310 rcall I2C_ACKEN ; send master acknowledge
1311
1312 rcall I2C_RCEN ; enable receive mode
1313 movff SSP1BUF,xC+2 ; copy received byte to xC+2
1314 rcall I2C_ACKEN ; send master acknowledge
1315
1316 rcall I2C_RCEN ; enable receive mode
1317 movff SSP1BUF,xC+1 ; copy received byte to xC+1
1318 rcall I2C_ACKEN ; send master acknowledge
1319
1320 rcall I2C_RCEN ; enable receive mode
1321 movff SSP1BUF,xC+0 ; copy received byte to xC+0
1322 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1323
1324 MOVLI .159,xB ; 159,4745717 (0,085mAh/533nAh)
1325 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder
1326
1327 ; clamp to 100% here
1328 tstfsz xC+2 ; Devision result > 0xFFFF
1329 setf xC+0 ; Yes, make sure xC:2 is 0xFFFF
1330 tstfsz xC+2 ; Devision result > 0xFFFF
1331 setf xC+1 ; Yes, make sure xC:2 is 0xFFFF
1332
1333 movff xC+1,sub_a+1
1334 movff xC+0,sub_a+0 ; put result in sub_a:2
1335 ;
1336 ; movff sub_a+1,gp_debug+1
1337 ; movff sub_a+0,gp_debug+0
1338 ;
1339 bra lt2942_get_accumulated_charge2 ; continue as with LT2942
1340
1341
1248 lt2942_set_to_zero_percent: 1342 lt2942_set_to_zero_percent:
1343 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1344 bra LTC2959_set_to_zero_percent
1345
1249 movlw 0x02 ; point to accumulated charge registers 1346 movlw 0x02 ; point to accumulated charge registers
1250 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1347 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1251 movff battery_offset+1,SSP1BUF ; send battery offset, high byte 1348 movff battery_offset+1,SSP1BUF ; send battery offset, high byte
1252 rcall WaitMSSP ; wait for TX to complete 1349 rcall WaitMSSP ; wait for TX to complete
1253 rcall I2C_Check_ACK ; check for acknowledge by receiver 1350 rcall I2C_Check_ACK ; check for acknowledge by receiver
1254 movff battery_offset+0,SSP1BUF ; send battery offset, low byte 1351 movff battery_offset+0,SSP1BUF ; send battery offset, low byte
1255 rcall WaitMSSP ; wait for TX to complete 1352 rcall WaitMSSP ; wait for TX to complete
1256 rcall I2C_Check_ACK ; check for acknowledge by receiver 1353 rcall I2C_Check_ACK ; check for acknowledge by receiver
1257 bsf SSP1CON2,PEN ; stop condition 1354 bra I2C_PEN ; stop condition (and return)
1355
1356 LTC2959_set_to_zero_percent:
1357 ; multiply battery_offset:2 with 159 and write result to LTC2959
1358
1359 MOVII battery_offset,xA
1360 MOVLI .159,xB ; 159,4745717 (0,085mAh/533nAh)
1361 call mult16x16 ; xC:4 = xA:2 * xB:2
1362
1363 movlw 0x03 ; point to accumulated charge registers
1364 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1365 movff xC+3,SSP1BUF ; send battery offset
1258 rcall WaitMSSP ; wait for TX to complete 1366 rcall WaitMSSP ; wait for TX to complete
1259 return ; done 1367 rcall I2C_Check_ACK ; check for acknowledge by receiver
1260 1368 movff xC+2,SSP1BUF ; send battery offset
1369 rcall WaitMSSP ; wait for TX to complete
1370 rcall I2C_Check_ACK ; check for acknowledge by receiver
1371 movff xC+1,SSP1BUF ; send battery offset
1372 rcall WaitMSSP ; wait for TX to complete
1373 rcall I2C_Check_ACK ; check for acknowledge by receiver
1374 movff xC+0,SSP1BUF ; send battery offset
1375 rcall WaitMSSP ; wait for TX to complete
1376 rcall I2C_Check_ACK ; check for acknowledge by receiver
1377 bra I2C_PEN ; stop condition (and return)
1378
1261 1379
1262 ;----------------------------------------------------------------------------- 1380 ;-----------------------------------------------------------------------------
1263 ; Read Gauge IC - Reset Accumulating Register to 0xFFFF 1381 ; Read Gauge IC - Reset Accumulating Register to 0xFFFF
1264 ; 1382 ;
1265 global lt2942_charge_done 1383 global lt2942_charge_done
1266 lt2942_charge_done: 1384 lt2942_charge_done:
1385 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1386 bra lt2959_charge_done
1387
1267 movlw 0x02 ; point to accumulated charge registers 1388 movlw 0x02 ; point to accumulated charge registers
1268 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC 1389 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1269 setf SSP1BUF ; data byte 1390 setf SSP1BUF ; data byte
1270 rcall WaitMSSP ; wait for TX to complete 1391 rcall WaitMSSP ; wait for TX to complete
1271 rcall I2C_Check_ACK ; check for acknowledge by receiver 1392 rcall I2C_Check_ACK ; check for acknowledge by receiver
1272 setf SSP1BUF ; data byte 1393 setf SSP1BUF ; data byte
1273 rcall WaitMSSP ; wait for TX to complete 1394 rcall WaitMSSP ; wait for TX to complete
1274 rcall I2C_Check_ACK ; check for acknowledge by receiver 1395 rcall I2C_Check_ACK ; check for acknowledge by receiver
1275 bsf SSP1CON2,PEN ; stop condition 1396 bra I2C_PEN ; stop condition (and return)
1397
1398 lt2959_charge_done:
1399 ; Reset Accumulating Register to 0x009EFF61 (0xFFFF * .159)
1400 movlw 0x03 ; point to accumulated charge registers
1401 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC
1402 movlw 0x00
1403 movwf SSP1BUF ; data byte
1276 rcall WaitMSSP ; wait for TX to complete 1404 rcall WaitMSSP ; wait for TX to complete
1277 return ; done 1405 rcall I2C_Check_ACK ; check for acknowledge by receiver
1278 1406 movlw 0x9E
1279 1407 movwf SSP1BUF ; data byte
1408 rcall WaitMSSP ; wait for TX to complete
1409 rcall I2C_Check_ACK ; check for acknowledge by receiver
1410 movlw 0xFF
1411 movwf SSP1BUF ; data byte
1412 rcall WaitMSSP ; wait for TX to complete
1413 rcall I2C_Check_ACK ; check for acknowledge by receiver
1414 movlw 0x61
1415 movwf SSP1BUF ; data byte
1416 rcall WaitMSSP ; wait for TX to complete
1417 rcall I2C_Check_ACK ; check for acknowledge by receiver
1418 bra I2C_PEN ; stop condition (and return)
1419
1420
1280 ;----------------------------------------------------------------------------- 1421 ;-----------------------------------------------------------------------------
1281 ; Helper Function - send 1 Byte to the LT2942 Gauge IC 1422 ; Helper Function - send 1 Byte to the LT2942 Gauge IC
1282 ; 1423 ;
1283 I2C_TX_GAUGE: 1424 I2C_TX_GAUGE:
1284 movwf i2c_temp2 ; save data byte to be sent 1425 movwf i2c_temp2 ; save data byte to be sent
1285 bsf SSP1CON2,SEN ; start condition 1426 rcall I2C_SEN ; start condition
1286 rcall WaitMSSP ; wait for TX to complete 1427 movlw 0xC8 ; address byte + Write bit LT2942
1287 movlw 0xC8 ; address byte + Write bit 1428 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1288 movff WREG,i2c_error_vault+0 ; Store address 1429 movlw 0xC6 ; address byte + Write bit LTC2559
1289 movwf SSP1BUF ; control byte 1430 rcall I2C_TX ; send byte
1290 rcall WaitMSSP ; wait for TX to complete
1291 rcall I2C_Check_ACK ; check for acknowledge by receiver
1292 movf i2c_temp2,W ; restore data byte to be sent 1431 movf i2c_temp2,W ; restore data byte to be sent
1293 bra I2C_TX ; send byte and return 1432 bra I2C_TX ; send byte and return
1294 1433
1295 1434
1296 ;----------------------------------------------------------------------------- 1435 ;-----------------------------------------------------------------------------
1297 ; Helper Function - receive 1 Byte from the LT2942 Gauge IC 1436 ; Helper Function - receive 1 Byte from the LT2942 Gauge IC
1298 ; 1437 ;
1299 I2C_RX_GAUGE: 1438 I2C_RX_GAUGE:
1300 bsf SSP1CON2,RSEN ; repeated start condition 1439 rcall I2C_RSEN ; repeated start condition
1301 rcall WaitMSSP ; wait for TX to complete 1440 movlw 0xC9 ; address byte + Read bit LT2942
1302 movlw 0xC9 ; address byte + Read bit 1441 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942
1303 movff WREG,i2c_error_vault+0 ; Store address 1442 movlw 0xC7 ; address byte + Read bit LTC2959
1304 movwf SSP1BUF ; control byte 1443 rcall I2C_TX ; send byte
1305 rcall WaitMSSP ; wait for TX to complete 1444 bra I2C_RCEN ; enable receive mode
1306 rcall I2C_Check_ACK ; check for acknowledge by receiver
1307 bsf SSP1CON2,RCEN ; enable receive mode
1308 bra WaitMSSP ; wait for reception and return
1309 1445
1310 1446
1311 ;----------------------------------------------------------------------------- 1447 ;-----------------------------------------------------------------------------
1312 ; Reset Hardware and Software Battery Gauge 1448 ; Reset Hardware and Software Battery Gauge
1313 ; 1449 ;
1314 ; called from comm.asm and menu_tree.asm 1450 ; called from comm.asm and menu_tree.asm
1315 ; 1451 ;
1316 global reset_battery_gauge_and_lt2942 1452 global reset_battery_gauge_and_lt2942
1317 reset_battery_gauge_and_lt2942: 1453 reset_battery_gauge_and_lt2942:
1318 btfsc battery_gauge_available ; battery gauge chip available? 1454 btfsc battery_gauge_available ; battery gauge chip available?
1319 call lt2942_charge_done ; YES - reset meter to 0xFFFF 1455 call lt2942_charge_done ; YES - reset meter to 0xFFFF
1320 ;bra reset_battery_gauge ; continue resetting gauge registers 1456 ;bra reset_battery_gauge ; continue resetting gauge registers
1321 1457
1322 1458
1323 ;----------------------------------------------------------------------------- 1459 ;-----------------------------------------------------------------------------
1355 movff WREG,rx_firmware_cur_major ; ... current TR module firmware, major 1491 movff WREG,rx_firmware_cur_major ; ... current TR module firmware, major
1356 movff WREG,rx_firmware_cur_minor ; ... current TR module firmware, minor 1492 movff WREG,rx_firmware_cur_minor ; ... current TR module firmware, minor
1357 movlw .5 ; max number of tries for detecting a TR module 1493 movlw .5 ; max number of tries for detecting a TR module
1358 movwf hy ; initialize loop counter for tries 1494 movwf hy ; initialize loop counter for tries
1359 I2C_probe_OSTC_rx_1: 1495 I2C_probe_OSTC_rx_1:
1360 bsf SSP1CON2,SEN ; start condition 1496 rcall I2C_SEN ; start condition
1361 rcall WaitMSSP ; wait for TX to complete
1362 movlw 0x50 ; address byte + write bit 1497 movlw 0x50 ; address byte + write bit
1363 movff WREG,i2c_error_vault+0 ; Store address 1498 rcall I2C_TX ; send byte
1364 movwf SSP1BUF ; control byte
1365 rcall WaitMSSP ; wait for TX to complete
1366 btfss SSP1CON2,ACKSTAT ; ACK received?
1367 bsf ostc_rx_present ; YES - TR module detected 1499 bsf ostc_rx_present ; YES - TR module detected
1368 bsf SSP1CON2,PEN ; stop condition 1500 rcall I2C_PEN ; stop condition
1369 rcall WaitMSSP ; wait for TX to complete
1370 btfss ostc_rx_present ; was a TR module detected? 1501 btfss ostc_rx_present ; was a TR module detected?
1371 return ; NO - done 1502 return ; NO - done
1372 1503
1373 WAITMS .1 ; wait 1 ms 1504 WAITMS .1 ; wait 1 ms
1374 bsf SSP1CON2,SEN ; start condition 1505 rcall I2C_SEN ; start condition
1375 rcall WaitMSSP ; wait for TX to complete
1376 movlw 0x50 ; address byte + write bit 1506 movlw 0x50 ; address byte + write bit
1377 movwf SSP1BUF ; control byte 1507 rcall I2C_TX ; send byte
1378 rcall WaitMSSP ; wait for TX to complete
1379 rcall I2C_Check_ACK ; check for acknowledge by receiver
1380 movlw 0x1B ; command: get firmware 1508 movlw 0x1B ; command: get firmware
1381 movwf SSP1BUF ; send command 1509 rcall I2C_TX ; send byte
1382 rcall WaitMSSP ; wait for TX to complete 1510 rcall I2C_PEN ; stop condition
1383 rcall I2C_Check_ACK ; check for acknowledge by receiver
1384 bsf SSP1CON2,PEN ; stop condition
1385 rcall WaitMSSP ; wait for TX to complete
1386 1511
1387 WAITMS .1 ; wait 1 ms 1512 WAITMS .1 ; wait 1 ms
1388 1513
1389 bsf SSP1CON2,SEN ; start condition 1514 rcall I2C_SEN ; start condition
1390 rcall WaitMSSP ; wait for TX to complete
1391 movlw 0x51 ; address byte + Read bit 1515 movlw 0x51 ; address byte + Read bit
1392 movwf SSP1BUF ; control byte 1516 movwf SSP1BUF ; control byte
1393 rcall WaitMSSP ; wait for TX to complete 1517 rcall WaitMSSP ; wait for TX to complete
1394 bsf SSP1CON2,RCEN ; enable receive mode 1518 rcall I2C_RCEN ; enable receive mode
1395 rcall WaitMSSP ; wait for TX to complete
1396 movff SSP1BUF,rx_firmware_cur_major ; store as firmware version, major 1519 movff SSP1BUF,rx_firmware_cur_major ; store as firmware version, major
1397 bsf SSP1CON2,ACKEN ; master acknowledge 1520 rcall I2C_ACKEN ; send master acknowledge
1398 rcall WaitMSSP ; wait for TX to complete
1399 1521
1400 ; last byte in read from RX circuity always with a NACK! 1522 ; last byte in read from RX circuity always with a NACK!
1401 bsf SSP1CON2,RCEN ; enable receive mode 1523 rcall I2C_RCEN ; enable receive mode
1402 rcall WaitMSSP ; wait for TX to complete
1403 movff SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor 1524 movff SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor
1404 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1525 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1405 1526
1406 ; wait for TR module becoming ready 1527 ; wait for TR module becoming ready
1407 movff rx_firmware_cur_minor,i2c_temp1 ; copy minor firmware version to bank common 1528 movff rx_firmware_cur_minor,i2c_temp1 ; copy minor firmware version to bank common
1426 ;----------------------------------------------------------------------------- 1547 ;-----------------------------------------------------------------------------
1427 ; OSTC TR - get Tank Data 1548 ; OSTC TR - get Tank Data
1428 ; 1549 ;
1429 global I2C_get_tankdata 1550 global I2C_get_tankdata
1430 I2C_get_tankdata: 1551 I2C_get_tankdata:
1431 bsf SSP1CON2,SEN ; start condition 1552 rcall I2C_SEN ; start condition
1432 rcall WaitMSSP ; wait for TX to complete
1433 movlw 0x50 ; address byte + write bit 1553 movlw 0x50 ; address byte + write bit
1434 movff WREG,i2c_error_vault+0 ; Store address 1554 rcall I2C_TX ; send byte
1435 movwf SSP1BUF ; control byte
1436 rcall WaitMSSP ; wait for TX to complete
1437 rcall I2C_Check_ACK ; check for acknowledge by receiver
1438 movlw 0x1E ; read buffer2 (48 bytes) 1555 movlw 0x1E ; read buffer2 (48 bytes)
1439 movwf SSP1BUF ; data byte 1556 rcall I2C_TX ; send byte
1440 rcall WaitMSSP ; wait for TX to complete 1557 rcall I2C_PEN ; stop condition
1441 rcall I2C_Check_ACK ; check for acknowledge by receiver
1442 bsf SSP1CON2,PEN ; stop condition
1443 rcall WaitMSSP ; wait for TX to complete
1444 1558
1445 WAITMS .1 ; wait 1 ms 1559 WAITMS .1 ; wait 1 ms
1446 1560
1447 ; read 48 bytes 1561 ; read 48 bytes
1448 bsf SSP1CON2,SEN ; start condition 1562 rcall I2C_SEN ; start condition
1449 rcall WaitMSSP ; wait for TX to complete
1450 movlw 0x51 ; address byte + read bit 1563 movlw 0x51 ; address byte + read bit
1451 movwf SSP1BUF ; control byte 1564 rcall I2C_TX ; send byte
1452 rcall WaitMSSP ; wait for TX to complete
1453 rcall I2C_Check_ACK ; check for acknowledge by receiver
1454 movlw .47 ; 47 with ACK + 1 w/o ACK 1565 movlw .47 ; 47 with ACK + 1 w/o ACK
1455 movwf i2c_temp2 ; initialize loop counter 1566 movwf i2c_temp2 ; initialize loop counter
1456 lfsr FSR2,rx_buffer ; point to start of rx data buffer 1567 lfsr FSR2,rx_buffer ; point to start of rx data buffer
1457 I2C_get_tankdata_loop_read: 1568 I2C_get_tankdata_loop_read:
1458 bsf SSP1CON2,RCEN ; enable receive mode 1569 rcall I2C_RCEN ; enable receive mode
1459 rcall WaitMSSP ; wait for TX to complete
1460 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer 1570 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer
1461 bcf SSP1CON2,ACKDT ; reset ACKDT flag 1571 bcf SSP1CON2,ACKDT ; reset ACKDT flag
1462 bsf SSP1CON2,ACKEN ; master acknowledge 1572 rcall I2C_ACKEN ; send master acknowledge
1463 rcall WaitMSSP ; wait for TX to complete
1464 decfsz i2c_temp2,F ; decrement loop counter, done? 1573 decfsz i2c_temp2,F ; decrement loop counter, done?
1465 bra I2C_get_tankdata_loop_read ; NO - loop 1574 bra I2C_get_tankdata_loop_read ; NO - loop
1466 ; read last byte without ACK 1575 ; read last byte without ACK
1467 bsf SSP1CON2,RCEN ; enable receive mode 1576 rcall I2C_RCEN ; enable receive mode
1468 rcall WaitMSSP ; wait for TX to complete
1469 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer 1577 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer
1470 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1578 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1471 return ; done 1579 return ; done
1472 1580
1473 1581
1483 bcf i2c_error_flag ; clear error flag 1591 bcf i2c_error_flag ; clear error flag
1484 lfsr FSR2,buffer ; initialize pointer to send buffer used for verify 1592 lfsr FSR2,buffer ; initialize pointer to send buffer used for verify
1485 movlw .64 ; initialize loop counter: 64 byte with ACK 1593 movlw .64 ; initialize loop counter: 64 byte with ACK
1486 movwf i2c_temp2 ; ... 1594 movwf i2c_temp2 ; ...
1487 ; address write 1595 ; address write
1488 bsf SSP1CON2,SEN ; start condition 1596 rcall I2C_SEN ; start condition
1489 rcall WaitMSSP ; wait for TX to complete
1490 movlw 0x50 ; address byte + write bit 1597 movlw 0x50 ; address byte + write bit
1491 movff WREG,i2c_error_vault+0 ; Store address 1598 rcall I2C_TX ; send byte
1492 movwf SSP1BUF ; control byte
1493 rcall WaitMSSP ; wait for TX to complete
1494 rcall I2C_Check_ACK ; check for acknowledge by receiver
1495 ; write 64 bytes 1599 ; write 64 bytes
1496 I2C_update_OSTC_loop: 1600 I2C_update_OSTC_loop:
1497 TBLRD*+ ; read a byte from program memory 1601 TBLRD*+ ; read a byte from program memory
1498 movff TABLAT,POSTINC2 ; copy to send buffer 1602 movff TABLAT,POSTINC2 ; copy to send buffer
1499 movff TABLAT,SSP1BUF ; copy to I2C data buffer 1603 movf TABLAT,W ; copy to W
1500 rcall WaitMSSP ; wait for TX to complete 1604 rcall I2C_TX ; send byte
1501 rcall I2C_Check_ACK ; check for acknowledge by receiver
1502 decfsz i2c_temp2,F ;decrement loop counter, became zero? 1605 decfsz i2c_temp2,F ;decrement loop counter, became zero?
1503 bra I2C_update_OSTC_loop ; NO - loop 1606 bra I2C_update_OSTC_loop ; NO - loop
1504 bsf SSP1CON2,PEN ; YES - stop condition 1607 rcall I2C_PEN ; stop condition
1505 rcall WaitMSSP ; - wait for TX to complete
1506 WAITMS .1 ; - wait another 1 ms 1608 WAITMS .1 ; - wait another 1 ms
1507 ; setup for read-back 1609 ; setup for read-back
1508 lfsr FSR2,buffer ; reset pointer to begin of send buffer 1610 lfsr FSR2,buffer ; reset pointer to begin of send buffer
1509 movlw .63 ; initialize loop counter: 63 byte with ACK + 1 w/o ACK 1611 movlw .63 ; initialize loop counter: 63 byte with ACK + 1 w/o ACK
1510 movwf i2c_temp2 ; ... 1612 movwf i2c_temp2 ; ...
1511 ; address read-back 1613 ; address read-back
1512 bsf SSP1CON2,SEN ; start condition 1614 rcall I2C_SEN ; start condition
1513 rcall WaitMSSP ; wait for TX to complete
1514 movlw 0x51 ; address byte + read bit 1615 movlw 0x51 ; address byte + read bit
1515 movwf SSP1BUF ; control byte 1616 rcall I2C_TX ; send byte
1516 rcall WaitMSSP ; wait for TX to complete
1517 rcall I2C_Check_ACK ; check for acknowledge by receiver
1518 ; read-back 64 bytes 1617 ; read-back 64 bytes
1519 I2C_update_OSTC_loop_read: 1618 I2C_update_OSTC_loop_read:
1520 bsf SSP1CON2,RCEN ; enable receive mode 1619 rcall I2C_RCEN ; enable receive mode
1521 rcall WaitMSSP ; wait for TX to complete
1522 movf SSP1BUF,W ; copy received byte to WREG 1620 movf SSP1BUF,W ; copy received byte to WREG
1523 cpfseq POSTINC2 ; compare read-back byte with sent byte, equal? 1621 cpfseq POSTINC2 ; compare read-back byte with sent byte, equal?
1524 bsf i2c_error_flag ; NO - not equal, set error flag 1622 bsf i2c_error_flag ; NO - not equal, set error flag
1525 bcf SSP1CON2,ACKDT ; reset ACKDT flag 1623 bcf SSP1CON2,ACKDT ; reset ACKDT flag
1526 bsf SSP1CON2,ACKEN ; master acknowledge 1624 rcall I2C_ACKEN ; send master acknowledge
1527 rcall WaitMSSP ; wait for TX to complete
1528 decfsz i2c_temp2,F ; decrement loop counter, became zero? 1625 decfsz i2c_temp2,F ; decrement loop counter, became zero?
1529 bra I2C_update_OSTC_loop_read ; NO - loop 1626 bra I2C_update_OSTC_loop_read ; NO - loop
1530 ; 1 w/o ACK 1627 ; 1 w/o ACK
1531 bsf SSP1CON2, RCEN ; YES - enable receive mode 1628 bsf SSP1CON2, RCEN ; YES - enable receive mode
1532 rcall WaitMSSP ; - wait for TX to complete 1629 rcall WaitMSSP ; - wait for TX to complete
1534 cpfseq POSTINC2 ; - compare read-back byte with sent byte, equal? 1631 cpfseq POSTINC2 ; - compare read-back byte with sent byte, equal?
1535 bsf i2c_error_flag ; NO - not equal, set error flag 1632 bsf i2c_error_flag ; NO - not equal, set error flag
1536 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1633 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1537 WAITMS .1 1634 WAITMS .1
1538 ; address commit 1635 ; address commit
1539 bsf SSP1CON2,SEN ; start condition 1636 rcall I2C_SEN ; start condition
1540 rcall WaitMSSP ; wait for TX to complete
1541 movlw 0x50 ; address byte + write bit 1637 movlw 0x50 ; address byte + write bit
1542 movwf SSP1BUF ; control byte 1638 rcall I2C_TX ; send byte
1543 rcall WaitMSSP ; wait for TX to complete
1544 rcall I2C_Check_ACK ; check for acknowledge by receiver
1545 movlw 0x1F ; write command 1639 movlw 0x1F ; write command
1546 movwf SSP1BUF ; data byte 1640 rcall I2C_TX ; send byte
1547 rcall WaitMSSP ; wait for TX to complete 1641 rcall I2C_PEN ; stop condition
1548 rcall I2C_Check_ACK ; check for acknowledge by receiver
1549 bsf SSP1CON2,PEN ; stop condition
1550 rcall WaitMSSP ; wait for TX to complete
1551 WAITMS .5 ; required waiting time 1642 WAITMS .5 ; required waiting time
1552 ; error check 1643 ; error check
1553 btfss i2c_error_flag ; did an error occur? 1644 btfss i2c_error_flag ; did an error occur?
1554 retlw .0 ; NO - data transfered successfully 1645 retlw .0 ; NO - data transfered successfully
1555 retlw .255 ; YES - error in data transfer occurred 1646 retlw .255 ; YES - error in data transfer occurred
1562 ; Probe for MS5837 sensor 1653 ; Probe for MS5837 sensor
1563 ; 1654 ;
1564 global I2C_probe_pressure_sensor ; Do not call from ISR! 1655 global I2C_probe_pressure_sensor ; Do not call from ISR!
1565 I2C_probe_pressure_sensor: ; Probe the type of sensor, set/clear press_sensor_type 1656 I2C_probe_pressure_sensor: ; Probe the type of sensor, set/clear press_sensor_type
1566 bcf press_sensor_type ; MS5541 as default 1657 bcf press_sensor_type ; MS5541 as default
1567 bsf SSP1CON2,SEN ; start condition 1658 rcall I2C_SEN ; start condition
1568 rcall WaitMSSP ; wait for TX to complete
1569 movlw 0xEC ; address byte + write bit 1659 movlw 0xEC ; address byte + write bit
1570 movff WREG,i2c_error_vault+0 ; Store address
1571 movwf SSP1BUF ; control byte 1660 movwf SSP1BUF ; control byte
1572 rcall WaitMSSP ; wait for TX to complete 1661 rcall WaitMSSP ; wait for TX to complete
1662 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit!
1573 btfss SSP1CON2,ACKSTAT ; ACK received? 1663 btfss SSP1CON2,ACKSTAT ; ACK received?
1574 bsf press_sensor_type ; MS5837 sensor found 1664 bsf press_sensor_type ; MS5837 sensor found
1575 bsf SSP1CON2,PEN ; stop condition 1665 bra I2C_PEN ; stop condition
1576 rcall WaitMSSP ; wait for TX to complete
1577 return
1578 1666
1579 ;-------------------------------------------------------------------- 1667 ;--------------------------------------------------------------------
1580 ; Helper Function - get the calibration parameter from # WREG address 1668 ; Helper Function - get the calibration parameter from # WREG address
1581 ; Do not call from ISR! 1669 ; Do not call from ISR!
1582 I2C_get_calib_parameter: 1670 I2C_get_calib_parameter:
1583 movwf lo ; store address 1671 movwf lo ; store address
1584 bsf SSP1CON2,SEN ; start condition 1672 rcall I2C_SEN ; start condition
1585 rcall WaitMSSP ; wait for TX to complete
1586 movlw 0xEC ; address byte + write bit 1673 movlw 0xEC ; address byte + write bit
1587 movff WREG,i2c_error_vault+0 ; Store address
1588 rcall I2C_TX ; send byte 1674 rcall I2C_TX ; send byte
1589 movf lo,W ; Point to calibration register 1675 movf lo,W ; Point to calibration register
1590 rcall I2C_TX ; send byte 1676 rcall I2C_TX ; send byte
1591 bsf SSP1CON2,PEN ; stop condition 1677 rcall I2C_PEN ; stop condition
1592 rcall WaitMSSP ; wait for TX to complete 1678
1593 1679 rcall I2C_SEN ; start condition
1594 bsf SSP1CON2,SEN ; start condition
1595 rcall WaitMSSP ; wait for TX to complete
1596 movlw 0xED ; address byte + read bit 1680 movlw 0xED ; address byte + read bit
1597 movff WREG,i2c_error_vault+0 ; Store address 1681 rcall I2C_TX ; send byte
1598 movwf SSP1BUF ; control byte 1682 rcall I2C_RCEN ; enable receive mode
1599 rcall WaitMSSP ; wait for TX to complete
1600 rcall I2C_Check_ACK ; check for acknowledge by receiver
1601 bsf SSP1CON2,RCEN ; enable receive mode
1602 rcall WaitMSSP ; wait for reception and return
1603 movff SSP1BUF,dMSB ; High byte 1683 movff SSP1BUF,dMSB ; High byte
1604 bsf SSP1CON2,ACKEN ; master acknowledge 1684 rcall I2C_ACKEN ; send master acknowledge
1605 rcall WaitMSSP ; wait for TX to complete 1685
1606 1686 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge
1607 bsf SSP1CON2,RCEN ; enable receive mode
1608 rcall WaitMSSP ; wait for reception
1609 movff SSP1BUF,dLSB ; Low byte 1687 movff SSP1BUF,dLSB ; Low byte
1610 ; bsf SSP1CON2,ACKDT ; set ACKDT flag 1688 bra I2C_PEN ; stop condition
1611 bsf SSP1CON2,ACKEN ; master acknowledge
1612 rcall WaitMSSP ; wait for TX to complete
1613 ; bcf SSP1CON2,ACKDT ; reset ACKDT flag
1614 bsf SSP1CON2,PEN ; stop condition
1615 bra WaitMSSP ; wait for TX to complete (And return)
1616 1689
1617 1690
1618 global I2C_get_calib_MS5837 ; Do not call from ISR! 1691 global I2C_get_calib_MS5837 ; Do not call from ISR!
1619 I2C_get_calib_MS5837: 1692 I2C_get_calib_MS5837:
1620 banksel common 1693 banksel common
1621 ; first, send a reset 1694 ; first, send a reset
1622 bsf SSP1CON2,SEN ; start condition 1695 rcall I2C_SEN ; start condition
1623 rcall WaitMSSP ; wait for TX to complete
1624 movlw 0xEC ; address byte + write bit 1696 movlw 0xEC ; address byte + write bit
1625 movff WREG,i2c_error_vault+0 ; Store address
1626 rcall I2C_TX ; send byte 1697 rcall I2C_TX ; send byte
1627 movlw 0x1E 1698 movlw 0x1E
1628 rcall I2C_TX ; send byte 1699 rcall I2C_TX ; send byte
1629 bsf SSP1CON2,PEN ; stop condition 1700 rcall I2C_PEN ; stop condition
1630 rcall WaitMSSP ; wait for TX to complete
1631 WAITMS .5 ; 2.8ms according to datasheet 1701 WAITMS .5 ; 2.8ms according to datasheet
1632 1702
1633 movlw 0xA2 ; Point to C1 1703 movlw 0xA2 ; Point to C1
1634 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi 1704 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi
1635 movff dLSB,C1+0 ; store calib 1705 movff dLSB,C1+0 ; store calib
1662 1732
1663 return 1733 return
1664 1734
1665 global I2C_get_press_val_MS5837 1735 global I2C_get_press_val_MS5837
1666 I2C_get_press_val_MS5837: 1736 I2C_get_press_val_MS5837:
1667 bsf SSP1CON2,SEN ; start condition 1737 btfsc i2c_reinit_sensor2 ; Sensor ok?
1668 rcall WaitMSSP ; wait for TX to complete 1738 rcall I2CReset ; Try a I2C reset first
1739 btfsc i2c_reinit_sensor2 ; Sensor ok?
1740 bra I2C_get_press_val_MS5837_skip ; We did a reset, restart conversion first
1741
1742 rcall I2C_SEN ; start condition
1669 movlw 0xEC ; address byte + write bit 1743 movlw 0xEC ; address byte + write bit
1670 movff WREG,i2c_error_vault+0 ; Store address
1671 rcall I2C_TX ; send byte 1744 rcall I2C_TX ; send byte
1672 movlw 0x00 ; command byte (0x00, read ADC) 1745 movlw 0x00 ; command byte (0x00, read ADC)
1673 rcall I2C_TX ; send byte 1746 rcall I2C_TX ; send byte
1674 1747
1675 bsf SSP1CON2,RSEN ; repeated start condition 1748 rcall I2C_RSEN ; repeated start condition
1676 rcall WaitMSSP ; wait for TX to complete
1677 movlw 0xED ; address byte + read bit 1749 movlw 0xED ; address byte + read bit
1678 movff WREG,i2c_error_vault+0 ; Store address 1750 rcall I2C_TX ; send byte
1679 movwf SSP1BUF ; control byte
1680 rcall WaitMSSP ; wait for TX to complete
1681 rcall I2C_Check_ACK ; check for acknowledge by receiver
1682 1751
1683 bsf i2c_busy_pressure ; reading new pressure 1752 bsf i2c_busy_pressure ; reading new pressure
1684 bsf SSP1CON2,RCEN ; enable receive mode 1753 rcall I2C_RCEN ; enable receive mode
1685 rcall WaitMSSP ; wait for reception and return
1686 movff SSP1BUF,D1_buffer+2 ; Upper byte 1754 movff SSP1BUF,D1_buffer+2 ; Upper byte
1687 bsf SSP1CON2,ACKEN ; master acknowledge 1755 rcall I2C_ACKEN ; send master acknowledge
1688 rcall WaitMSSP ; wait for TX to complete 1756 rcall I2C_RCEN ; enable receive mode
1689 bsf SSP1CON2,RCEN ; enable receive mode
1690 rcall WaitMSSP ; wait for reception
1691 movff SSP1BUF,D1_buffer+1 ; high byte 1757 movff SSP1BUF,D1_buffer+1 ; high byte
1692 bsf SSP1CON2,ACKEN ; master acknowledge 1758 rcall I2C_ACKEN ; send master acknowledge
1693 rcall WaitMSSP ; wait for TX to complete 1759 rcall I2C_RCEN ; enable receive mode
1694 bsf SSP1CON2,RCEN ; enable receive mode
1695 rcall WaitMSSP ; wait for reception
1696 movff SSP1BUF,D1_buffer+0 ; Low byte 1760 movff SSP1BUF,D1_buffer+0 ; Low byte
1697 1761
1698 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1762 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1699 bcf i2c_busy_pressure ; reading new pressure done. 1763 bcf i2c_busy_pressure ; reading new pressure done.
1700 1764
1765 I2C_get_press_val_MS5837_skip:
1701 ; Start temperature measurement 1766 ; Start temperature measurement
1702 bsf SSP1CON2,SEN ; start condition 1767 rcall I2C_SEN ; start condition
1703 rcall WaitMSSP ; wait for TX to complete
1704 movlw 0xEC ; address byte + write bit 1768 movlw 0xEC ; address byte + write bit
1705 rcall I2C_TX ; send byte 1769 rcall I2C_TX ; send byte
1706 movlw 0x58 ; OSR=4096, type=D2 1770 movlw 0x58 ; OSR=4096, type=D2
1707 rcall I2C_TX ; send byte 1771 rcall I2C_TX ; send byte
1708 bsf SSP1CON2,PEN ; stop condition 1772 rcall I2C_PEN ; stop condition
1709 rcall WaitMSSP ; wait for TX to complete
1710 bcf ms5837_state ; =0: result of temperature will be in the ADC 1773 bcf ms5837_state ; =0: result of temperature will be in the ADC
1774 bcf i2c_reinit_sensor2 ; Clear error flag
1711 return 1775 return
1712 1776
1713 global I2C_get_temp_val_MS5837 1777 global I2C_get_temp_val_MS5837
1714 I2C_get_temp_val_MS5837: 1778 I2C_get_temp_val_MS5837:
1715 bsf SSP1CON2,SEN ; start condition 1779 btfsc i2c_reinit_sensor2 ; Sensor ok?
1716 rcall WaitMSSP ; wait for TX to complete 1780 rcall I2CReset ; Try a I2C reset first
1781 btfsc i2c_reinit_sensor2 ; Sensor ok?
1782 bra I2C_get_temp_val_MS5837_skip ; We did a reset, restart conversion first
1783
1784 rcall I2C_SEN ; start condition
1717 movlw 0xEC ; address byte + write bit 1785 movlw 0xEC ; address byte + write bit
1718 movff WREG,i2c_error_vault+0 ; Store address
1719 rcall I2C_TX ; send byte 1786 rcall I2C_TX ; send byte
1720 movlw 0x00 ; command byte (0x00, read ADC) 1787 movlw 0x00 ; command byte (0x00, read ADC)
1721 rcall I2C_TX ; send byte 1788 rcall I2C_TX ; send byte
1722 1789
1723 bsf SSP1CON2,RSEN ; repeated start condition 1790 rcall I2C_RSEN ; repeated start condition
1724 rcall WaitMSSP ; wait for TX to complete
1725 movlw 0xED ; address byte + read bit 1791 movlw 0xED ; address byte + read bit
1726 movff WREG,i2c_error_vault+0 ; Store address 1792 rcall I2C_TX ; send byte
1727 movwf SSP1BUF ; control byte
1728 rcall WaitMSSP ; wait for TX to complete
1729 rcall I2C_Check_ACK ; check for acknowledge by receiver
1730 1793
1731 bsf i2c_busy_temperature ; reading new temperature 1794 bsf i2c_busy_temperature ; reading new temperature
1732 bsf SSP1CON2,RCEN ; enable receive mode 1795 rcall I2C_RCEN ; enable receive mode
1733 rcall WaitMSSP ; wait for reception and return
1734 movff SSP1BUF,D2_buffer+2 ; Upper byte 1796 movff SSP1BUF,D2_buffer+2 ; Upper byte
1735 bsf SSP1CON2,ACKEN ; master acknowledge 1797 rcall I2C_ACKEN ; send master acknowledge
1736 rcall WaitMSSP ; wait for TX to complete 1798 rcall I2C_RCEN ; enable receive mode
1737 bsf SSP1CON2,RCEN ; enable receive mode
1738 rcall WaitMSSP ; wait for reception
1739 movff SSP1BUF,D2_buffer+1 ; high byte 1799 movff SSP1BUF,D2_buffer+1 ; high byte
1740 bsf SSP1CON2,ACKEN ; master acknowledge 1800 rcall I2C_ACKEN ; send master acknowledge
1741 rcall WaitMSSP ; wait for TX to complete 1801 rcall I2C_RCEN ; enable receive mode
1742 bsf SSP1CON2,RCEN ; enable receive mode
1743 rcall WaitMSSP ; wait for reception
1744 movff SSP1BUF,D2_buffer+0 ; Low byte 1802 movff SSP1BUF,D2_buffer+0 ; Low byte
1745 1803
1746 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop 1804 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop
1747 bcf i2c_busy_temperature ; reading new temperature done. 1805 bcf i2c_busy_temperature ; reading new temperature done.
1748 1806
1807 I2C_get_temp_val_MS5837_skip:
1749 ; Start pressure measurement 1808 ; Start pressure measurement
1750 bsf SSP1CON2,SEN ; start condition 1809 rcall I2C_SEN ; start condition
1751 rcall WaitMSSP ; wait for TX to complete
1752 movlw 0xEC ; address byte + write bit 1810 movlw 0xEC ; address byte + write bit
1753 rcall I2C_TX ; send byte 1811 rcall I2C_TX ; send byte
1754 movlw 0x48 ; OSR=4096, type=D1 1812 movlw 0x48 ; OSR=4096, type=D1
1755 rcall I2C_TX ; send byte 1813 rcall I2C_TX ; send byte
1756 bsf SSP1CON2,PEN ; stop condition 1814 rcall I2C_PEN ; stop condition
1757 rcall WaitMSSP ; wait for TX to complete
1758 bsf ms5837_state ; =0: result of pressure will be in the ADC 1815 bsf ms5837_state ; =0: result of pressure will be in the ADC
1816 bcf i2c_reinit_sensor2 ; Clear error flag
1759 return 1817 return
1760 1818
1761 1819
1762 ;----------------------------------------------------------------------------- 1820 ;-----------------------------------------------------------------------------
1763 ; I2C Bus error checker 1821 ; I2C Bus error checker
1765 global check_i2c_error 1823 global check_i2c_error
1766 extern TFT_message_i2c_error 1824 extern TFT_message_i2c_error
1767 check_i2c_error: 1825 check_i2c_error:
1768 btfss i2c_error_flag 1826 btfss i2c_error_flag
1769 return 1827 return
1828 bcf i2c_error_flag_lock ; arm error vault again
1770 incf message_counter,F ; increase message counter 1829 incf message_counter,F ; increase message counter
1771 goto TFT_message_i2c_error ; show message for battery low (battery percent) and return 1830 goto TFT_message_i2c_error ; show message for battery low (battery percent) and return
1772 1831
1773 ;----------------------------------------------------------------------------- 1832 ;-----------------------------------------------------------------------------
1774 END 1833 END