diff src/i2c.asm @ 626:be8787f2034d

compass3 support for 3.01 branch
author heinrichsweikamp
date Sun, 23 Jun 2019 15:21:16 +0200
parents 1ad0531e9078
children
line wrap: on
line diff
--- a/src/i2c.asm	Sun Jun 23 13:29:17 2019 +0200
+++ b/src/i2c.asm	Sun Jun 23 15:21:16 2019 +0200
@@ -1,568 +1,608 @@
 ;=============================================================================
 ;
-;   File i2c.asm														V2.99c
+;   File i2c.asm
 ;
 ;   I2C Interface
+;   
+    ; Compass0
+;   HMC5883L's read address (8-Bit):    0x3D
+;   HMC5883L's write address (8-Bit):   0x3C
+;   MMA8452Q's read address (8-Bit):    0x39
+;   MMA8452Q's write address (8-Bit):   0x38
+;
+    ; Compass1
+;   LSM303D's read address (8-Bit):    0x3D
+;   LSM303D's write address (8-Bit):   0x3C
+;
+    ; Compass2
+;   LSM303AGR's Compass read address (8-Bit):    0x3D
+;   LSM303AGR's Compass write address (8-Bit):   0x3C
+;   LSM303AGR's Acceleration read address (8-Bit):    0x33
+;   LSM303AGR's Acceleration write address (8-Bit):   0x32
+;    
+    ; Compass3
+;   LSM303C's Compass read address (8-Bit):    0x3D
+;   LSM303C's Compass write address (8-Bit):   0x3C
+;   LSM303C's Acceleration read address (8-Bit):    0x3B
+;   LSM303C's Acceleration write address (8-Bit):   0x3A
+;
+    ; RX Circuity
+;   RX Circuity read address (8-Bit):    0x51
+;   RX Circuity write address (8-Bit):   0x50
+;
 ;
 ;   Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved.
 ;=============================================================================
-;
-;   Compass0
-;   --------
-;   HMC5883L's read address  (8-Bit):  0x3D
-;   HMC5883L's write address (8-Bit):  0x3C
-;   MMA8452Q's read address  (8-Bit):  0x39
-;   MMA8452Q's write address (8-Bit):  0x38
-;
-;   Compass1
-;   --------
-;   LSM303D's read address  (8-Bit):   0x3D
-;   LSM303D's write address (8-Bit):   0x3C
-;
-;   Compass2
-;   --------
-;   LSM303AGR's Compass read address       (8-Bit):  0x3D
-;   LSM303AGR's Compass write address      (8-Bit):  0x3C
-;   LSM303AGR's Acceleration read address  (8-Bit):  0x33
-;   LSM303AGR's Acceleration write address (8-Bit):  0x32
-;
-;   RX Circuity
-;   -----------
-;   RX Circuity read address  (8-Bit):  0x51
-;   RX Circuity write address (8-Bit):  0x50
-;
-;
-
 ; HISTORY
 ;  2012-08-22 : [mH] Creation
-;  2018-02-18 : [mH] Sync with hwOS Sport release
 
 
-#include "hwos.inc"						; Mandatory header
+#include "hwos.inc"                ; Mandatory header
 #include "wait.inc"
 #include "math.inc"
 #include "external_flash.inc"
 
-
-i2c		CODE
-
-;=============================================================================
+i2c    CODE
 
 I2C_TX:
-	movwf	SSP1BUF
-	rcall	WaitMSSP
-	bra		I2C_WaitforACK				; returns...
+	movwf		SSP1BUF
+	rcall		WaitMSSP
+	bra 		I2C_WaitforACK      ; Returns...
 
-I2C_TwoBytesRX_div16:					; get two bytes and divide lo:hi/16 (signed)
-	rcall	I2C_OneByteRX				; get one byte
-	movff	SSP1BUF,hi					; data byte
-	rcall	I2C_OneByteRX				; get one byte
-	movff	SSP1BUF,lo					; data byte
-I2C_TwoBytesRX_div16_2:					; divide lo:hi/16 (signed) only
-	bcf		STATUS,C
-	btfsc	hi,7						; copy sign bit to carry
-	bsf		STATUS,C
-	rrcf	hi							; /2
-	rrcf	lo
-I2C_TwoBytesRX_div8_2:					; divide lo:hi/8 (signed) only
-	bcf		STATUS,C
-	btfsc	hi,7						; copy sign bit to carry
-	bsf		STATUS,C
-	rrcf	hi							; /4
-	rrcf	lo
-	bcf		STATUS,C
-	btfsc	hi,7						; copy sign bit to carry
-	bsf		STATUS,C
-	rrcf	hi							; /8
-	rrcf	lo
-	bcf		STATUS,C
-	btfsc	hi,7						; copy sign bit to carry
-	bsf		STATUS,C
-	rrcf	hi							; /16
-	rrcf	lo
-	return
+I2C_TwoBytesRX_div16:       ; Get two bytes and devide lo:hi/16 (signed)
+    rcall       I2C_OneByteRX       ; Get one byte
+	movff		SSP1BUF,hi          ; Data Byte
+    rcall       I2C_OneByteRX       ; Get one byte
+	movff		SSP1BUF,lo          ; Data Byte
+I2C_TwoBytesRX_div16_2:     ; devide lo:hi/16 (signed) only
+    bcf			STATUS,C
+    btfsc       hi,7        ; Copy sign bit to carry
+    bsf         STATUS,C
+    rrcf		hi          ; /2
+    rrcf		lo
+I2C_TwoBytesRX_div8_2:     ; devide lo:hi/8 (signed) only
+    bcf			STATUS,C
+    btfsc       hi,7        ; Copy sign bit to carry
+    bsf         STATUS,C
+    rrcf		hi          ; /4
+    rrcf		lo
+    bcf			STATUS,C
+    btfsc       hi,7        ; Copy sign bit to carry
+    bsf         STATUS,C
+    rrcf		hi          ; /8
+	rrcf		lo
+    bcf			STATUS,C
+    btfsc       hi,7        ; Copy sign bit to carry
+    bsf         STATUS,C
+    rrcf		hi          ; /16
+	rrcf		lo
+    return
 
-	global	I2C_RX_accelerometer
+    global  I2C_RX_accelerometer
 I2C_RX_accelerometer:
-	btfsc	compass_type2					; compass2 ?
-	bra		I2C_RX_accelerometer_compass2	; YES
-	btfsc	compass_type					; compass1 ?
-	bra		I2C_RX_accelerometer_compass1	; YES
+    btfsc   compass_type3	    ; compass3
+    bra	    I2C_RX_accelerometer_compass3    ; yes
+    btfsc   compass_type2	    ; compass2
+    bra	    I2C_RX_accelerometer_compass2    ; yes
+    btfsc   compass_type	    ; compass1?
+    bra	    I2C_RX_accelerometer_compass1    ; yes
 I2C_RX_accelerometer_compass0:
-	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
-	movlw	0x38						; address
-	rcall	I2C_TX
-	movlw	0x00
-	rcall	I2C_TX
-	bsf		SSP1CON2,RSEN				; repeated start condition
-	rcall	WaitMSSP
-	movlw	0x39						; address
-	rcall	I2C_TX
-
-	rcall	I2C_OneByteRX				; get status byte
-	movf	SSP1BUF,W
+    bsf			SSP1CON2,SEN		; Start condition
+    rcall		WaitMSSP
+    movlw		0x38                ; address
+    rcall       I2C_TX
+    movlw		0x00
+    rcall       I2C_TX
+    bsf			SSP1CON2,RSEN		; Repeated start condition (!)
+    rcall		WaitMSSP
+    movlw		0x39                ; address
+    rcall       I2C_TX
 
-	; Non-flipped screen:
-	; Chip orientation on the PCB requires
-	; Original = corrected
-	; x = -x
-	; y = -y
-	; z = -z
+    rcall       I2C_OneByteRX       ; Get Status Byte
+    movf        SSP1BUF,W
+
+    ; Non-flipped screen:
+    ; Chip orientation on the PCB requires
+    ; Original = Corrected
+    ; x = -x
+    ; y = -y
+    ; z = -z
 
-	; Flipped screen:
-	; Chip orientation on the PCB requires
-	; Original = corrected
-	; x = x
-	; y = y
-	; z = -z
+    ; Flipped screen:
+    ; Chip orientation on the PCB requires
+    ; Original = Corrected
+    ; x = x
+    ; y = y
+    ; z = -z
 
-	rcall	I2C_TwoBytesRX_div16		; get two bytes and divide /16 (signed)
-	btfsc	flip_screen					; 180° rotation ?
-	bra		I2C_RX_accelerometer2		; YES
-	comf	hi							; 16 bit sign change
-	negf	lo
-	btfsc	STATUS,C					; carry to propagate ?
-	incf	hi,F						; YES - do it
+    rcall       I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed)
+    btfsc       flip_screen             ; 180° rotation ?
+    bra         I2C_RX_accelerometer2   ; Yes
+    comf        hi                    ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
 I2C_RX_accelerometer2:
-	movff	lo,accel_DX+0
-	movff	hi,accel_DX+1				; Copy result
+    movff       lo,accel_DX+0
+    movff       hi,accel_DX+1       ; Copy result
 
-	rcall	I2C_TwoBytesRX_div16		; Get two bytes and divide /16 (signed)
-	btfsc	flip_screen					; 180° rotation ?
-	bra		I2C_RX_accelerometer3		; Yes
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
+    rcall       I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed)
+    btfsc       flip_screen             ; 180° rotation ?
+    bra         I2C_RX_accelerometer3   ; Yes
+    comf        hi                    ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
 I2C_RX_accelerometer3:
-	movff	lo,accel_DY+0
-	movff	hi,accel_DY+1				; Copy result
+    movff       lo,accel_DY+0
+    movff       hi,accel_DY+1       ; Copy result
 
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,hi					; Data Byte
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
-; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+0)...
-	movff	SSP1BUF,lo					; Data Byte
+    rcall       I2C_OneByteRX       ; Get one byte
+	movff		SSP1BUF,hi          ; Data Byte
+	bsf			SSP1CON2, RCEN      ; Enable recieve mode
+    rcall		WaitMSSP
+; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+0)...
+	movff		SSP1BUF,lo          ; Data Byte
 
-	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
-	movff	lo,accel_DZ+0
-	movff	hi,accel_DZ+1				; Copy result
+    rcall       I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only
+    comf        hi                    ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
+    movff       lo,accel_DZ+0
+    movff       hi,accel_DZ+1       ; Copy result
 
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					; (And return)
+	bsf			SSP1CON2,PEN		; Stop condition
+	bra		WaitMSSP	; (And return)
 
 I2C_RX_accelerometer_compass1:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	b'10101000'					; 0x28 with auto-increment (MSB=1)
-	rcall	I2C_TX
-	bsf		SSP1CON2,RSEN				; Repeated start condition (!)
-	rcall	WaitMSSP
-	movlw	0x3D						; address
-I2C_RX_accelerometer_compass1_xx:		; compass2 continues here... 
-	rcall	I2C_TX
-
-	; Non-flipped screen:
-	; Chip orientation on the PCB requires
-	; Original = Corrected
-	; x = -x (Compass 1)
-	; x = x (Compass 2)
-	; y = -y
-	; z = -z
-
-	; Flipped screen:
-	; Chip orientation on the PCB requires
-	; Original = Corrected
-	; x = x (Compass 1)
-	; x = -x (Compass 2)
-	; y = y
-	; z = -z
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	b'10101000'	    ; 0x28 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    bsf		SSP1CON2,RSEN	    ; Repeated start condition (!)
+    rcall	WaitMSSP
+    movlw	0x3D                ; address
+I2C_RX_accelerometer_compass1_xx:   ; compass2 and 3 continue here... 
+    rcall       I2C_TX
+    ; Non-flipped screen:
+    ; Chip orientation on the PCB requires
+    ; Original = Corrected
+    ; x = -x (Compass 1)
+    ; x = x (Compass 2)
+    ; y = -y
+    ; z = -z
 
-	; Dump the accelerator data
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,lo					; accel_DX+0
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,hi  ;accel_DX+1
-	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
-	btfss	compass_type2				; compass 2?
-	bra		I2C_RX_accelerometer1_c1	; No, compass 1
-	; compass 2
-	btfss	flip_screen					; 180° rotation ?
-	bra		I2C_RX_accelerometer2_c1	; No, continue with normal compass1 routines for Y and Z
-	; flipped compass 2, negate x
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
-	bra		I2C_RX_accelerometer2_c1	; continue with normal compass1 routines for Y and Z
-
-I2C_RX_accelerometer1_c1:
-	btfsc	flip_screen					; 180° rotation ?
-	bra		I2C_RX_accelerometer2_c1	; Yes
-	; non-flipped compass 1, negate x
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
+    ; Flipped screen:
+    ; Chip orientation on the PCB requires
+    ; Original = Corrected
+    ; x = x (Compass 1)
+    ; x = -x (Compass 2)
+    ; y = y
+    ; z = -z
+    
+    ; Dump the accelerator data
+    rcall       I2C_OneByteRX       
+    movff	SSP1BUF,lo  ;accel_DX+0
+    rcall       I2C_OneByteRX       
+    movff	SSP1BUF,hi  ;accel_DX+1
+    rcall       I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only
+    btfss	compass_type2	    ; compass 2?
+    bra		I2C_RX_accelerometer1_c1    ; No, compass 1
+    ; compass 2
+    btfss       flip_screen             ; 180° rotation ?
+    bra		I2C_RX_accelerometer2_c1    ; No, continue with normal compass1 routines for Y and Z
+    ; flipped compass 2, negate x
+    comf        hi                    ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
+    bra		I2C_RX_accelerometer2_c1    ; continue with normal compass1 routines for Y and Z
+    
+I2C_RX_accelerometer1_c1:    
+    btfsc       flip_screen             ; 180° rotation ?
+    bra         I2C_RX_accelerometer2_c1   ; Yes
+    ; non-flipped compass 1, negate x
+    comf        hi                    ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
 I2C_RX_accelerometer2_c1:
-	; flipped compass 1, non-flipped compass 2
-	movff	lo,accel_DX+0
-	movff	hi,accel_DX+1				; Copy result
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,lo					; accel_DY+0
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,hi					; accel_DY+1
-
-	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
-	btfsc	flip_screen					; 180° rotation ?
-	bra		I2C_RX_accelerometer3_c1	; Yes
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
+    ; flipped compass 1, non-flipped compass 2
+    movff       lo,accel_DX+0
+    movff       hi,accel_DX+1       ; Copy result
+    rcall       I2C_OneByteRX       
+    movff	SSP1BUF,lo  ;accel_DY+0
+    rcall       I2C_OneByteRX       
+    movff	SSP1BUF,hi  ;accel_DY+1
+    
+    rcall       I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only
+    btfsc       flip_screen             ; 180° rotation ?
+    bra         I2C_RX_accelerometer3_c1   ; Yes
+    comf        hi                    ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
 I2C_RX_accelerometer3_c1:
-	movff	lo,accel_DY+0
-	movff	hi,accel_DY+1				; Copy result
+    movff       lo,accel_DY+0
+    movff       hi,accel_DY+1       ; Copy result
 
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,lo					;accel_DZ+0
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
-; According to data sheet there should be no Master Acknowledge for the last Byte (accel_DZ+1)...
-	movff	SSP1BUF,hi					;accel_DZ+1
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
-	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
-	comf	hi							; 16bit sign change for Z
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
-	movff	lo,accel_DZ+0
-	movff	hi,accel_DZ+1				; Copy result
-	return
+    rcall       I2C_OneByteRX     
+    movff	SSP1BUF,lo  ;accel_DZ+0
+    bsf		SSP1CON2, RCEN      ; Enable recieve mode
+    rcall	WaitMSSP
+; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+1)...
+    movff	SSP1BUF,hi  ;accel_DZ+1
+    bsf		SSP1CON2,PEN		; Stop condition
+    rcall	WaitMSSP
+    rcall       I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only
+    comf        hi                    ; 16bit sign change for Z
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
+    movff       lo,accel_DZ+0
+    movff       hi,accel_DZ+1       ; Copy result
+    return
 
 I2C_RX_accelerometer_compass2:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x32						; address
-	rcall	I2C_TX
-	movlw	b'10101000'					; 0x28 with auto-increment (MSB=1)
-	rcall	I2C_TX
-	bsf		SSP1CON2,RSEN				; Repeated start condition (!)
-	rcall	WaitMSSP
-	movlw	0x33						; address
-	bra		I2C_RX_accelerometer_compass1_xx
-
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x32                ; address
+    rcall       I2C_TX
+    movlw	b'10101000'	    ; 0x28 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    bsf		SSP1CON2,RSEN	    ; Repeated start condition (!)
+    rcall	WaitMSSP
+    movlw	0x33                ; address
+    bra		I2C_RX_accelerometer_compass1_xx
+    
+I2C_RX_accelerometer_compass3:
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x3A                ; address
+    rcall       I2C_TX
+    movlw	0x28		    ; 0x28 (OUT_X_L_A)
+    rcall       I2C_TX
+    bsf		SSP1CON2,RSEN	    ; Repeated start condition (!)
+    rcall	WaitMSSP
+    movlw	0x3B                ; address
+    bra		I2C_RX_accelerometer_compass1_xx
+    
 I2C_OneByteRX:
-	bsf		SSP1CON2,RCEN				; Enable receive mode
-	rcall	WaitMSSP
-	bsf		SSP1CON2,ACKEN				; Master acknowledge
-	bra		WaitMSSP					; And return!
+    bsf		SSP1CON2, RCEN      ; Enable recieve mode
+    rcall	WaitMSSP
+    bsf		SSP1CON2,ACKEN	    ; Master acknowlegde
+    bra		WaitMSSP	    ; And return!
 
-	global	I2C_RX_compass
+    global  I2C_RX_compass
 I2C_RX_compass:
-	btfsc	compass_type2				; compass2
-	bra		I2C_RX_compass2				; yes
-	btfsc	compass_type				; compass1?
-	bra		I2C_RX_compass1				; yes
+    btfsc   compass_type3	    ; compass3
+    bra	    I2C_RX_compass3    ; yes
+    btfsc   compass_type2	    ; compass2
+    bra	    I2C_RX_compass2    ; yes
+    btfsc   compass_type	    ; compass1?
+    bra	    I2C_RX_compass1    ; yes
 I2C_RX_compass0:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x03
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0x03
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    rcall	WaitMSSP
 
-	bcf		PIR1,SSP1IF
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3D						; address
-	rcall	I2C_TX
+    bcf		PIR1,SSP1IF
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3D                ; address
+    rcall       I2C_TX
 
-	; Compass IC sends data in following order:
-	; x MSB
-	; x LSB
-	; z MSB
-	; z LSB
-	; y MSB
-	; y LSB
+    ; Compass IC sends data in following order:
+    ; x MSB
+    ; x LSB
+    ; z MSB
+    ; z LSB
+    ; y MSB
+    ; y LSB
 
-	; Non-flipped screen
-	; Chip orientation on the PCB requires
-	; Original = Corrected
-	; x = -y
-	; z = z
-	; y = x
-
-	; Flipped screen
-	; Chip orientation on the PCB requires
-	; Original = Corrected
-	; x = y
-	; z = z
-	; y = -x
+    ; Non-flipped screen
+    ; Chip orientation on the PCB requires
+    ; Original = Corrected
+    ; x = -y
+    ; z = z
+    ; y = x
 
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,compass_DY+1		; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,compass_DY+0		; Data Byte
-	btfsc	flip_screen					; 180° rotation ?
-	bra		I2C_RX_compass0_2			; Yes
-	banksel	compass_DY
-	comf	compass_DY+1				; 16bit sign change.
-	negf	compass_DY+0
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	compass_DY+1,F				; YES: do it.
+    ; Flipped screen
+    ; Chip orientation on the PCB requires
+    ; Original = Corrected
+    ; x = y
+    ; z = z
+    ; y = -x
+
+    rcall       I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,compass_DY+1; Data Byte
+    rcall       I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,compass_DY+0; Data Byte
+    btfsc       flip_screen         ; 180° rotation ?
+    bra         I2C_RX_compass0_2     ; Yes
+    banksel compass_DY
+    comf        compass_DY+1        ; 16bit sign change.
+    negf        compass_DY+0
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        compass_DY+1,F      ; YES: do it.
 I2C_RX_compass0_2:
-	banksel	common
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,compass_DZ+1		; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,compass_DZ+0		; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,compass_DX+1		; Data Byte
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,compass_DX+0		; Data Byte
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
-	btfss	flip_screen					; 180° rotation ?
-	return								; No, done.
-	; Yes, flip X
-	banksel	compass_DX
-	comf	compass_DX+1				; 16bit sign change.
-	negf	compass_DX+0
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	compass_DX+1,F				; YES: do it.
-	banksel	common
-	return
-
-I2C_RX_compass1:						; New compass
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	b'10001000'					; 0x08 with auto-increment (MSB=1)
-	rcall	I2C_TX
-	bsf		SSP1CON2,RSEN				; Repeated start condition (!)
-	rcall	WaitMSSP
-	movlw	0x3D						; address
-	rcall	I2C_TX
-	;rcall	WaitMSSP					; Needed? (mH)
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,lo					; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,hi					; Data Byte
-	rcall	I2C_TwoBytesRX_div8_2
-	movff	lo,compass_DX+0
-	movff	hi,compass_DX+1
-	btfss	   flip_screen				; 180° rotation ?
-	bra		I2C_RX_compass1_1			; Yes
-	; Yes, flip X
-	banksel compass_DX
-	comf	compass_DX+1				; 16bit sign change.
-	negf	compass_DX+0
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	compass_DX+1,F				; YES: do it.
-	banksel	common
+    banksel common
+    rcall       I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,compass_DZ+1; Data Byte
+    rcall       I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,compass_DZ+0; Data Byte
+    rcall       I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,compass_DX+1; Data Byte
+    bsf		SSP1CON2, RCEN      ; Enable recieve mode
+    rcall	WaitMSSP
+    movff	SSP1BUF,compass_DX+0; Data Byte
+    bsf		SSP1CON2,PEN	    ; Stop condition
+    rcall	WaitMSSP
+    btfss       flip_screen         ; 180° rotation ?
+    return                          ; No, done.
+    ; Yes, flip X
+    banksel compass_DX
+    comf        compass_DX+1        ; 16bit sign change.
+    negf        compass_DX+0
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        compass_DX+1,F      ; YES: do it.
+    banksel common
+    return
+    
+I2C_RX_compass1: ; New compass
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	b'10001000'	    ; 0x08 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    bsf		SSP1CON2,RSEN	    ; Repeated start condition (!)
+    rcall	WaitMSSP
+    movlw	0x3D                ; address
+    rcall       I2C_TX
+;rcall	WaitMSSP	    ; Needed? (mH)
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,lo	    ; Data Byte
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,hi	    ; Data Byte
+    rcall	I2C_TwoBytesRX_div8_2
+    movff	lo,compass_DX+0
+    movff	hi,compass_DX+1
+    btfss       flip_screen         ; 180° rotation ?
+    bra		I2C_RX_compass1_1              ; Yes
+    ; Yes, flip X
+    banksel compass_DX
+    comf        compass_DX+1        ; 16bit sign change.
+    negf        compass_DX+0
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        compass_DX+1,F      ; YES: do it.
+    banksel common
 I2C_RX_compass1_1:
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,lo					; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,hi					; Data Byte
-	rcall	I2C_TwoBytesRX_div8_2
-	movff	lo,compass_DY+0
-	movff	hi,compass_DY+1
-	btfss	flip_screen					; 180° rotation ?
-	bra		I2C_RX_compass1_2			; Yes
-	; Yes, flip Y
-	banksel compass_DY
-	comf	compass_DY+1				; 16bit sign change.
-	negf	compass_DY+0
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	compass_DY+1,F				; YES: do it.
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,lo	    ; Data Byte
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,hi	    ; Data Byte
+    rcall	I2C_TwoBytesRX_div8_2
+    movff	lo,compass_DY+0
+    movff	hi,compass_DY+1
+    btfss       flip_screen         ; 180° rotation ?
+    bra         I2C_RX_compass1_2   ; Yes
+    ; Yes, flip Y
+    banksel compass_DY
+    comf        compass_DY+1        ; 16bit sign change.
+    negf        compass_DY+0
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        compass_DY+1,F      ; YES: do it.
 I2C_RX_compass1_2:
-	banksel	common
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,lo					; Data Byte
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,hi					; Data Byte
-	rcall	I2C_TwoBytesRX_div8_2
-	movff	lo,compass_DZ+0
-	movff	hi,compass_DZ+1
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					;(And return)
+    banksel common
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,lo	    ; Data Byte
+    bsf		SSP1CON2, RCEN      ; Enable recieve mode
+    rcall	WaitMSSP
+    movff	SSP1BUF,hi	    ; Data Byte
+    rcall	I2C_TwoBytesRX_div8_2
+    movff	lo,compass_DZ+0
+    movff	hi,compass_DZ+1
+    bsf		SSP1CON2,PEN	    ; Stop condition
+    bra		WaitMSSP ;(And return)
 
-I2C_RX_compass2:						; newest compass
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0xE8						; 0x68 with auto-increment (MSB=1)
-	rcall	I2C_TX
-	bsf		SSP1CON2,RSEN				; Repeated start condition (!)
-	rcall	WaitMSSP
-	movlw	0x3D						; address
-	rcall	I2C_TX
-;	rcall	WaitMSSP
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,lo					; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,hi					; Data Byte
-;	rcall	I2C_TwoBytesRX_div8_2
-	btfsc	flip_screen					; 180° rotation ?
-	bra		I2C_RX_compass2_1			; Yes, do nothing with X
-	; No, flip X
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
-I2C_RX_compass2_1:
-	movff	lo,compass_DX+0
-	movff	hi,compass_DX+1
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,lo					; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,hi					; Data Byte
-;	rcall	I2C_TwoBytesRX_div8_2
-	btfss	flip_screen					; 180° rotation ?
-	bra		I2C_RX_compass2_2			; No, do nothing with Y
-	; Yes, flip Y
-	comf	hi							; 16bit sign change.
-	negf	lo
-	btfsc	STATUS,C					; Carry to propagate ?
-	incf	hi,F						; YES: do it.
+I2C_RX_compass2:    ; newest compass
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0xE8		    ; 0x68 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    bsf		SSP1CON2,RSEN	    ; Repeated start condition (!)
+    rcall	WaitMSSP
+    movlw	0x3D                ; address
+    rcall       I2C_TX
+I2C_RX_compass2_xx:    ; compass 3 enters here
+;    rcall	WaitMSSP
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,lo	    ; Data Byte
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,hi	    ; Data Byte
+;    rcall	I2C_TwoBytesRX_div8_2
+    btfsc       flip_screen         ; 180° rotation ?
+    bra		I2C_RX_compass2_1   ; Yes, do nothing with X
+    ; No, flip X
+    comf        hi                  ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
+I2C_RX_compass2_1:   
+    movff	lo,compass_DX+0
+    movff	hi,compass_DX+1
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,lo	    ; Data Byte
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,hi	    ; Data Byte
+;    rcall	I2C_TwoBytesRX_div8_2
+    btfss       flip_screen         ; 180° rotation ?
+    bra		I2C_RX_compass2_2   ; No, do nothing with Y
+    ; Yes, flip Y
+    comf        hi                  ; 16bit sign change.
+    negf        lo
+    btfsc       STATUS,C            ; Carry to propagate ?
+    incf        hi,F                ; YES: do it.
 I2C_RX_compass2_2:   
-	movff	lo,compass_DY+0
-	movff	hi,compass_DY+1
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,lo					; Data Byte
-	rcall	I2C_OneByteRX				; Get one byte
-	movff	SSP1BUF,hi					; Data Byte
-;	rcall	I2C_TwoBytesRX_div8_2
-	movff	lo,compass_DZ+0
-	movff	hi,compass_DZ+1
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP ;(And return)
-
-
-	global	I2C_init_compass
-I2C_init_compass:
-	bsf		compass_enabled
-	bcf		compass_type2
-	; probe compass 2
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x32						; Address byte + Write bit
-	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	btfss	SSP1CON2,ACKSTAT			; ACK?
-	bsf		compass_type2				; ACK send. compass2 present
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
+    movff	lo,compass_DY+0
+    movff	hi,compass_DY+1
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,lo	    ; Data Byte
+    rcall	I2C_OneByteRX       ; Get one byte
+    movff	SSP1BUF,hi	    ; Data Byte
+    ;rcall	I2C_TwoBytesRX_div8_2
+    movff	lo,compass_DZ+0
+    movff	hi,compass_DZ+1
+    bsf		SSP1CON2,PEN	    ; Stop condition
+    bra		WaitMSSP ;(And return)
 
-	btfsc	compass_type2
-	bra		I2C_init_compass2			; Compass2
-	; Check for compass0 or compass1...
-	bsf		compass_type				; set flag
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x0F
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall   WaitMSSP
-	bcf		PIR1,SSP1IF
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3D						; address
-	rcall	I2C_TX
-	rcall	I2C_OneByteRX				; Get one byte
-	movlw	0x49						; 0x49 = Compass1
-	cpfseq	SSP1BUF
-	bcf		compass_type				; clear flag
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
+I2C_RX_compass3:
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0xA8		    ; 0x28 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    bsf		SSP1CON2,RSEN	    ; Repeated start condition (!)
+    rcall	WaitMSSP
+    movlw	0x3D                ; address
+    rcall       I2C_TX
+    bra		I2C_RX_compass2_xx
+    
+    global  I2C_init_compass
+I2C_init_compass:
+    bsf     compass_enabled
+    bcf	    compass_type2
+    bcf	    compass_type3
+    
+    ; probe compass 3
+    bsf	SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3A			; Address byte + Write bit
+    movwf	SSP1BUF			; control byte
+    rcall	WaitMSSP
+    btfss	SSP1CON2,ACKSTAT	; ACK?
+    bsf	    compass_type3		; ACK send. compass2 present
+    bsf	SSP1CON2,PEN		; Stop condition
+    rcall	WaitMSSP
+    
+    btfsc   compass_type3
+    bra	    I2C_init_compass3		; Compass3
+    
+    ; probe compass 2
+    bsf	SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x32			; Address byte + Write bit
+    movwf	SSP1BUF			; control byte
+    rcall	WaitMSSP
+    btfss	SSP1CON2,ACKSTAT	; ACK?
+    bsf	    compass_type2		; ACK send. compass2 present
+    bsf	SSP1CON2,PEN		; Stop condition
+    rcall	WaitMSSP
+    
+    btfsc   compass_type2
+    bra	    I2C_init_compass2		; Compass2
+    ; Check for compass0 or compass1...
+    bsf	    compass_type	    ; set flag
+    bsf	    SSP1CON2,SEN		; Start condition
+    rcall   WaitMSSP
+    movlw   0x3C                ; address
+    rcall   I2C_TX
+    movlw   0x0F
+    rcall   I2C_TX
+    bsf	    SSP1CON2,PEN		; Stop condition
+    rcall   WaitMSSP
+    bcf	    PIR1,SSP1IF
+    bsf	    SSP1CON2,SEN		; Start condition
+    rcall   WaitMSSP
+    movlw   0x3D                ; address
+    rcall   I2C_TX
+    rcall   I2C_OneByteRX       ; Get one byte
+    movlw   0x49		; 0x49 = Compass1
+    cpfseq  SSP1BUF
+    bcf	    compass_type	    ; clear flag
+    bsf	    SSP1CON2,PEN		; Stop condition
+    rcall   WaitMSSP
 
-	btfsc	compass_type				; compass1?
-	bra		I2C_init_compass1			; yes
+    btfsc   compass_type	    ; compass1?
+    bra	    I2C_init_compass1	    ; yes
 ; init compass0
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x00
-	rcall	I2C_TX
-;	movlw	b'01101001'					; ConfigA:  3Hz, 8 Samples averaged, Test Mode (Positive Bias)
-	movlw	b'01101000'					; ConfigA:  3Hz, 8 Samples averaged
-	rcall	I2C_TX
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0x00
+    rcall       I2C_TX
+;	movlw	b'01101001'        ; ConfigA:  3Hz, 8 Samples averaged, Test Mode (Positive Bias)
+    movlw	b'01101000'        ; ConfigA:  3Hz, 8 Samples averaged
+    rcall       I2C_TX
 I2C_init_compass_common:
-	movff	opt_compass_gain,i2c_temp1	; 0-7 (230LSB/Gauss to 1370LSB/Gauss)
-	swapf	i2c_temp1,F
-	comf	i2c_temp1,F
-	bcf		STATUS,C
-	rlcf	i2c_temp1
-	movf	i2c_temp1,W
-	clrf	i2c_temp1
-	rcall	I2C_TX
-	movlw	b'00000000'					; Continuous Mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					; (And return)
+    movff       opt_compass_gain,i2c_temp1    ; 0-7 (230LSB/Gauss to 1370LSB/Gauss)
+    swapf       i2c_temp1,F
+    comf        i2c_temp1,F
+    bcf         STATUS,C
+    rlcf        i2c_temp1
+    movf        i2c_temp1,W
+    clrf        i2c_temp1
+    rcall       I2C_TX
+    movlw	b'00000000'        ; Continous Mode
+    rcall       I2C_TX
+    bsf	SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
 
 I2C_init_compass1:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x9F						; 1F with auto-increment (MSB=1)
-	rcall	I2C_TX
-	movlw	b'00000000'					; CTRL0
-	rcall	I2C_TX
-	movlw	b'00101111'					; CTRL1 (6,25Hz, BDU=0, x,y,z = ON)
-	rcall	I2C_TX
-	movlw	b'11000000'					; CTRL2 (50Hz, +/-2g, 
-	rcall	I2C_TX
-	movlw	b'00000000'					; CTRL3
-	rcall	I2C_TX
-	movlw	b'00000000'					; CTRL4
-	rcall	I2C_TX
-	movlw	b'01100100'					; CTRL5 HIGH res, 6,25Hz
-	rcall	I2C_TX
+    bsf		SSP1CON2,SEN	; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C            ; address
+    rcall       I2C_TX
+    movlw	0x9F		; 1F with auto-increment (MSB=1)
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL0
+    rcall       I2C_TX
+    movlw	b'00101111'	; CTRL1 (6,25Hz, BDU=0, x,y,z = ON)
+    rcall       I2C_TX
+    movlw	b'11000000'	; CTRL2 (50Hz, +/-2g, 
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL3
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL4
+    rcall       I2C_TX
+    movlw	b'01100100'	; CTRL5 HIGH res, 6,25Hz
+    rcall       I2C_TX
 init_compass1_common:
-	movff	opt_compass_gain,i2c_temp1	; 0-7 (230LSB/Gauss to 1370LSB/Gauss) +++
-	movlw	b'01100000'					; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
-	dcfsnz	i2c_temp1,F					; = 1?
-	movlw	b'01100000'					; Yes, CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
-	dcfsnz	i2c_temp1,F					; = 2?
-	movlw	b'01000000'					; Yes, CTRL6 (+/-8 Gauss)
-	dcfsnz	i2c_temp1,F					; = 3?
-	movlw	b'01000000'					; Yes, CTRL6 (+/-8 Gauss)
-	dcfsnz	i2c_temp1,F					; = 4?
-	movlw	b'00100000'					; Yes, CTRL6 (+/-4 Gauss)
-	dcfsnz	i2c_temp1,F					; = 5?
-	movlw	b'00100000'					; Yes, CTRL6 (+/-4 Gauss)
-	dcfsnz	i2c_temp1,F					; = 6?
-	movlw	b'00000000'					; Yes, CTRL6 (+/-2 Gauss)
-	dcfsnz	i2c_temp1,F					; = 7?
-	movlw	b'00000000'					; Yes, CTRL6 (+/-2 Gauss)
-	rcall	I2C_TX
-	movlw	b'00000000'					; CTRL7 Continuous Mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					; (And return)
-
+    movff       opt_compass_gain,i2c_temp1    ; 0-7 (230LSB/Gauss to 1370LSB/Gauss)
+    movlw	b'01100000'	; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
+    dcfsnz	i2c_temp1,F	; = 1?
+    movlw	b'01100000'	; Yes, CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss)
+    dcfsnz	i2c_temp1,F	; = 2?
+    movlw	b'01000000'	; Yes, CTRL6 (+/-8 Gauss)
+    dcfsnz	i2c_temp1,F	; = 3?
+    movlw	b'01000000'	; Yes, CTRL6 (+/-8 Gauss)
+    dcfsnz	i2c_temp1,F	; = 4?
+    movlw	b'00100000'	; Yes, CTRL6 (+/-4 Gauss)
+    dcfsnz	i2c_temp1,F	; = 5?
+    movlw	b'00100000'	; Yes, CTRL6 (+/-4 Gauss)
+    dcfsnz	i2c_temp1,F	; = 6?
+    movlw	b'00000000'	; Yes, CTRL6 (+/-2 Gauss)
+    dcfsnz	i2c_temp1,F	; = 7?
+    movlw	b'00000000'	; Yes, CTRL6 (+/-2 Gauss)
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL7 Continuous Mode
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
+    
 I2C_init_compass2:
     bsf		SSP1CON2,SEN	; Start condition
     rcall	WaitMSSP
@@ -570,61 +610,147 @@
     rcall       I2C_TX
     movlw	0xE0		; 0x60 with auto-increment (MSB=1)
     rcall       I2C_TX
-    movlw	b'00000000'	; CFG_REG_A_M (10Hz, Continuous) 0x60
+    movlw	b'10000000'	; CFG_REG_A_M (10Hz, Continuous) 0x60
     rcall       I2C_TX
-    movlw	b'00000000'	; CFG_REG_B_M (Low-Pass Filter off) 0x61 (set pulse is released every 63 ODR)
+    movlw	b'00000001'	; CFG_REG_B_M (Low-Pass Filter enabled) 0x61 (set pulse is released every 63 ODR)
     rcall       I2C_TX
-    movlw	b'00000000'	; CFG_REG_C_M BDU=0 0x62
+    movlw	b'00010000'	; CFG_REG_C_M BDU=1 0x62
     rcall       I2C_TX
     bsf		SSP1CON2,PEN	; Stop condition
     bra		WaitMSSP	;(And return)
 
+I2C_init_compass3:
+    bsf		SSP1CON2,SEN	; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C            ; address
+    rcall       I2C_TX
+    movlw	0xA0		; 0x20 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    movlw	b'01110000'	; CTRL_REG1_M (10Hz) 0x20
+    rcall       I2C_TX
+    movlw	b'01100000'	; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21
+    rcall       I2C_TX
+    movlw	b'01000000'	; CTRL_REG3_M (Continuous) 0x22
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG4_M (Z in Low-power mode) 0x23
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG5_M 0x24
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG5_M 0x24
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN	; Stop condition
+    bra		WaitMSSP	;(And return)
+    
+    
+WaitMSSP:
+	decfsz		i2c_temp1,F          ; check for timeout during I2C action
+	bra		WaitMSSP2
+	bra		I2CFail             ; timeout occured
+WaitMSSP2:
+	btfss		PIR1,SSP1IF
+	bra		WaitMSSP
+	clrf		i2c_temp1
+	bcf		PIR1,SSP1IF
+	return
 
-	global	I2C_sleep_compass
+I2C_WaitforACK:
+	btfss		SSP1CON2,ACKSTAT     ; checks for ACK bit from slave
+	return
+I2CFail:
+	rcall		I2CReset            ; I2C Reset
+	bcf		PIR1,SSP1IF
+	clrf		i2c_temp1
+	bsf		i2c_error_flag		; set error flag
+	return
+
+I2CReset:                           ; Something went wrong (Slave holds SDA low?)
+	clrf		SSP1CON1            ; wake-up slave and reset entire module
+	clrf		SSP1CON2
+	clrf		SSP1STAT
+	bcf			TRISC,3             ; SCL OUTPUT
+	bsf			TRISC,4             ; SDA Input
+	bcf			PORTC,3
+	movlw		d'9'
+	movwf		i2c_temp1            ; clock-out 9 clock cycles manually
+I2CReset_1:
+	bsf			PORTC,3             ; SCL=1
+	nop
+	nop
+	nop
+	nop
+	btfsc		PORTC,4             ; SDA=1?
+	bra			I2CReset_2          ; =1, SDA has been released from slave
+	bcf			PORTC,3             ; SCL=0
+	nop
+	nop
+	bcf			PORTC,3
+	nop
+	nop
+	decfsz		i2c_temp1,F
+	bra         I2CReset_1          ; check for nine clock cycles
+I2CReset_2:
+	bsf			TRISC,3             ; SCL Input
+	clrf		SSP1CON1            ; setup I²C Mode
+	WAITMS		d'10'               ; Reset-Timeout for I2C devices
+	movlw		b'00000000'         ; with slew rate control
+	movwf		SSP1STAT
+	movlw		b'00101000'
+	movwf		SSP1CON1
+	movlw		b'00000000'
+	movwf		SSP1CON2
+    movlw       0x27
+	movwf		SSP1ADD
+	return
+    
+    
+    global  I2C_sleep_compass
 I2C_sleep_compass:
-	bcf		 compass_enabled
-	btfsc	compass_type2				; compass2?
-	bra		I2C_sleep_compass2			; yes
-	btfsc	compass_type				; compass1?
-	bra		I2C_sleep_compass1			; yes
+    bcf         compass_enabled
+    btfsc	compass_type3	    ; compass3?
+    bra		I2C_sleep_compass3  ; yes
+    btfsc	compass_type2	    ; compass2?
+    bra		I2C_sleep_compass2  ; yes
+    btfsc	compass_type	    ; compass1?
+    bra		I2C_sleep_compass1  ; yes
 I2C_sleep_compass0:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x00
-	rcall	I2C_TX
-	movlw	b'01101000'					; ConfigA
-	rcall	I2C_TX
-	movlw	b'00100000'					; ConfigB
-	rcall	I2C_TX
-	movlw	b'00000010'					; Idle Mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					; (And return)
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0x00
+    rcall       I2C_TX
+    movlw	b'01101000'        ; ConfigA
+    rcall       I2C_TX
+    movlw	b'00100000'        ; ConfigB
+    rcall       I2C_TX
+    movlw	b'00000010'        ; Idle Mode
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
 
 I2C_sleep_compass1:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x20						; CTRL_REG1
-	rcall	I2C_TX
-	movlw	b'00000000'					; data for CTRL_REG1: acceleration sensor Power-down mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x26						; CTRL_REG7
-	rcall	I2C_TX
-	movlw	b'00000010'					; data for CTRL_REG7: magnetic sensor Power-down mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					;(And return)
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0x20		    ; CTRL_REG1
+    rcall       I2C_TX
+    movlw	b'00000000'         ; data for CTRL_REG1: acceleration sensor Power-down mode
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN	    ; Stop condition
+    rcall	WaitMSSP
+    bsf		SSP1CON2,SEN	    ; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C                ; address
+    rcall       I2C_TX
+    movlw	0x26		    ; CTRL_REG7
+    rcall       I2C_TX
+    movlw	b'00000010'         ; data for CTRL_REG7: magnetic sensor Power-down mode
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN	    ; Stop condition
+    bra		WaitMSSP	;(And return)
 
+    
 I2C_sleep_compass2:
     ; magnetic
     bsf		SSP1CON2,SEN	; Start condition
@@ -644,6 +770,19 @@
 
     bsf		SSP1CON2,PEN	; Stop condition
     bra		WaitMSSP	; (And return)
+
+I2C_sleep_compass3:
+    ; magnetic
+    bsf		SSP1CON2,SEN	; Start condition
+    rcall	WaitMSSP
+    movlw	0x3C            ; address
+    rcall       I2C_TX
+    movlw	0xA2		; 0x22 with auto-increment (MSB=1)
+    rcall       I2C_TX
+    movlw	b'01000010'	; CTRL_REG3_M (Power-down) 0x22
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN	; Stop condition
+    bra		WaitMSSP	;(And return)
     
 I2C_sleep_accelerometer2:
     ; accelerometer
@@ -660,153 +799,129 @@
     bsf		SSP1CON2,PEN	; Stop condition
     bra		WaitMSSP	; (And return)
 
-WaitMSSP:
-	decfsz	i2c_temp1,F					; check for timeout during I2C action
-	bra		WaitMSSP2
-	bra		I2CFail						; timeout occurred
-WaitMSSP2:
-	btfss	PIR1,SSP1IF
-	bra		WaitMSSP
-	clrf	i2c_temp1
-	bcf		PIR1,SSP1IF
-	return
+I2C_sleep_accelerometer3:
+    ; accelerometer
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3A            ; address
+    rcall       I2C_TX
+    movlw	0x20
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
+    
+   global  I2C_init_accelerometer
+I2C_init_accelerometer:
+    btfsc   compass_type3	    ; compass3?
+    bra	    I2C_init_accelerometer3 ; Yes.
+    btfsc   compass_type2	    ; compass2?
+    bra	    I2C_init_accelerometer2 ; Yes.
+    btfsc   compass_type	    ; compass1?
+    return			    ; yes, ignore
 
-I2C_WaitforACK:
-	btfss	SSP1CON2,ACKSTAT			; checks for ACK bit from slave
-	return
-I2CFail:
-	rcall	I2CReset					; I2C Reset
-	bcf		PIR1,SSP1IF
-	clrf	i2c_temp1
-	bsf		i2c_error_flag				; set error flag
-	return
+    rcall       I2C_sleep_accelerometer ; Regs can only be changed in St.By mode
 
-I2CReset:								; something went wrong (slave holds SDA low?)
-	clrf	SSP1CON1					; wake-up slave and reset entire module
-	clrf	SSP1CON2
-	clrf	SSP1STAT
-	bcf		TRISC,3						; SCL OUTPUT
-	bsf		TRISC,4						; SDA input
-	bcf		PORTC,3
-	movlw	d'9'
-	movwf	i2c_temp1					; clock-out 9 clock cycles manually
-I2CReset_1:
-	bsf		PORTC,3						; SCL = 1
-	nop
-	nop
-	nop
-	nop
-	btfsc	PORTC,4						; SDA = 1 ?
-	bra		I2CReset_2					; YES - =1, SDA has been released from slave
-	bcf		PORTC,3						; NO  - set SCL = 0
-	nop
-	nop
-	bcf		PORTC,3
-	nop
-	nop
-	decfsz	i2c_temp1,F
-	bra		I2CReset_1					; check for nine clock cycles
-I2CReset_2:
-	bsf		TRISC,3						; SCL Input
-	clrf	SSP1CON1					; setup I²C mode
-	WAITMS	d'10'						; reset-timeout for I2C devices
-	movlw	b'00000000'					; with slew rate control
-	movwf	SSP1STAT
-	movlw	b'00101000'
-	movwf	SSP1CON1
-	movlw	b'00000000'
-	movwf	SSP1CON2
-	movlw	0x27
-	movwf	SSP1ADD
-	return
-    
-	global	I2C_init_accelerometer
-I2C_init_accelerometer:
-	btfsc	compass_type2				; compass2?
-	bra		I2C_init_accelerometer2		; Yes.
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x38                ; address
+    rcall       I2C_TX
+    movlw	0x0E                ; XYZ_DATA_CFG
+    rcall       I2C_TX
+    movlw	b'00000000'         ; High pass Filter=0 , +/- 2g range
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    rcall	WaitMSSP
+
 
-	btfsc	compass_type				; compass1?
-	return								; yes, ignore
-
-	rcall	I2C_sleep_accelerometer		; Regs can only be changed in St.By mode
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x38                ; address
+    rcall       I2C_TX
+    movlw	0x2A                ; CTRL_REG1
+    rcall       I2C_TX
+;	movlw		b'00110000'         ; CTRL_REG1: 160ms data rate, St.By Mode
+    movlw	b'00110100'         ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode
+    rcall       I2C_TX
+    movlw	b'00000010'         ; CTRL_REG2: High Res in Active mode
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    rcall	WaitMSSP
 
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x38						; address
-	rcall	I2C_TX
-	movlw	0x0E						; XYZ_DATA_CFG
-	rcall	I2C_TX
-	movlw	b'00000000'					; High pass Filter=0 , +/- 2g range
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
-
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x38						; address
-	rcall	I2C_TX
-	movlw	0x2A						; CTRL_REG1
-	rcall	I2C_TX
-;	movlw	b'00110000'					; CTRL_REG1: 160ms data rate, St.By Mode
-	movlw	b'00110100'					; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode
-	rcall	I2C_TX
-	movlw	b'00000010'					; CTRL_REG2: High Res in Active mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
-
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x38						; address
-	rcall	I2C_TX
-	movlw	0x2A						; CTRL_REG1
-	rcall	I2C_TX
-;	movlw	b'00110001'					; CTRL_REG1: 160ms data rate, Active Mode
-	movlw	b'00110101'					; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					; (And return)
-
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x38                ; address
+    rcall       I2C_TX
+    movlw	0x2A                ; CTRL_REG1
+    rcall       I2C_TX
+;	movlw		b'00110001'         ; CTRL_REG1: 160ms data rate, Active Mode
+    movlw	b'00110101'         ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
+    
 I2C_init_accelerometer2:
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x32						; address
-	rcall	I2C_TX
-	movlw	0x9F						; 1F with auto-increment (MSB=1)
-	rcall	I2C_TX
-	movlw	b'00000000'					; TEMP_CFG_REG_A (Temp sensor off)
-	rcall	I2C_TX
-	movlw	b'01010111'					; CTRL_REG1_A (100Hz, x,y,z = ON)
-	rcall	I2C_TX
-	movlw	b'00000000'					; CTRL_REG2_A
-	rcall	I2C_TX
-;	movlw	b'00000000'					; CTRL_REG3_A
-;	rcall	I2C_TX
-;	movlw	b'00000000'					; CTRL_REG4_A (BDU=0, +/-2g,
-;	rcall	I2C_TX
-;	movlw	b'00000000'					; CTRL_REG5_A
-;	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra		WaitMSSP					; (And return)
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x32            ; address
+    rcall       I2C_TX
+    movlw	0x9F		; 1F with auto-increment (MSB=1)
+    rcall       I2C_TX
+    movlw	b'00000000'	; TEMP_CFG_REG_A (Temp sensor off) 0x1F
+    rcall       I2C_TX
+    movlw	b'01010111'	; CTRL_REG1_A (100Hz, x,y,z = ON) 0x20
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG2_A 0x21
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG3_A 0x22
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG4_A (BDU=0, +/-2g) 0x23
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG5_A 0x24
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
 
-	global	I2C_sleep_accelerometer
+I2C_init_accelerometer3:
+    bsf		SSP1CON2,SEN		; Start condition
+    rcall	WaitMSSP
+    movlw	0x3A            ; address
+    rcall       I2C_TX
+    movlw	0x20
+    rcall       I2C_TX
+    movlw	b'10011111'	; CTRL_REG1_A (10Hz, x,y,z = ON) 0x20
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG2_A 0x21
+    rcall       I2C_TX
+    movlw	b'00000000'	; CTRL_REG3_A 0x22
+    rcall       I2C_TX
+    movlw	b'11001100'	; CTRL_REG4_A 0x23
+    rcall       I2C_TX
+    bsf		SSP1CON2,PEN		; Stop condition
+    bra		WaitMSSP	; (And return)
+    
+    
+    global  I2C_sleep_accelerometer
 I2C_sleep_accelerometer:
-	btfsc	compass_type2				; Compass2
-	bra		I2C_sleep_accelerometer2	; Yes
-	btfsc	compass_type				; compass1?
-	return								; yes, ignore
-
-	bsf		SSP1CON2,SEN				; Start condition
-	rcall	WaitMSSP
-	movlw	0x38						; address
-	rcall	I2C_TX
-	movlw	0x2A						; CTRL_REG1
-	rcall	I2C_TX
-	movlw	b'00000000'					; St. By Mode
-	rcall	I2C_TX
-	bsf		SSP1CON2,PEN				; Stop condition
-	bra	WaitMSSP						; (And return)
-
+    btfsc   compass_type3	    ; Compass3
+    bra	    I2C_sleep_accelerometer3	; Yes
+    btfsc   compass_type2	    ; Compass2
+    bra	    I2C_sleep_accelerometer2	; Yes
+    btfsc   compass_type	    ; compass1?
+    return			    ; yes, ignore
+    ; compass 0
+	bsf			SSP1CON2,SEN		; Start condition
+	rcall		WaitMSSP
+	movlw		0x38                ; address
+    rcall       I2C_TX
+	movlw		0x2A                ; CTRL_REG1
+    rcall       I2C_TX
+	movlw		b'00000000'         ; St. By Mode
+    rcall       I2C_TX
+	bsf			SSP1CON2,PEN		; Stop condition
+	bra	WaitMSSP	    ; (And return)
+   
 lt2942_init_again:
 	clrf	i2c_temp1
 	movlw	0x02						; Point to accumulated charge registers