Mercurial > public > hwos_code
diff src/i2c.asm @ 427:ceb1b7329dce
add code for new compass chip
author | heinrichsweikamp |
---|---|
date | Tue, 14 Jun 2016 13:02:17 +0200 |
parents | 653a3ab08062 |
children | 4b93354b7738 |
line wrap: on
line diff
--- a/src/i2c.asm Fri Jun 10 10:01:42 2016 +0200 +++ b/src/i2c.asm Tue Jun 14 13:02:17 2016 +0200 @@ -10,6 +10,9 @@ ; MMA8452Q's read address (8-Bit): 0x39 ; MMA8452Q's write address (8-Bit): 0x38 ; +; LSM303D's read address (8-Bit): 0x3D +; LSM303D's write address (8-Bit): 0x3C +; ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= ; HISTORY @@ -100,12 +103,13 @@ btfsc hi,7 ; Copy sign bit to carry bsf STATUS,C rrcf hi ; /2 - rrcf lo + 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 + rrcf lo bcf STATUS,C btfsc hi,7 ; Copy sign bit to carry bsf STATUS,C @@ -120,15 +124,18 @@ global I2C_RX_accelerometer I2C_RX_accelerometer: - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x38 ; address + 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 + movlw 0x00 rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) - rcall WaitMSSP - movlw 0x39 ; address + bsf SSP1CON2,RSEN ; Repeated start condition (!) + rcall WaitMSSP + movlw 0x39 ; address rcall I2C_TX rcall I2C_OneByteRX ; Get Status Byte @@ -189,28 +196,105 @@ rcall WaitMSSP 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 + rcall I2C_TX + + ; 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 + + ; 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 + btfsc flip_screen ; 180° rotation ? + bra I2C_RX_accelerometer2_c1 ; Yes + comf hi ; 16bit sign change. + negf lo + btfsc STATUS,C ; Carry to propagate ? + incf hi,F ; YES: do it. +I2C_RX_accelerometer2_c1: + 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 + + 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_OneByteRX: - bsf SSP1CON2, RCEN ; Enable recieve mode - rcall WaitMSSP - bsf SSP1CON2,ACKEN ; Master acknowlegde - rcall WaitMSSP - return + bsf SSP1CON2, RCEN ; Enable recieve mode + rcall WaitMSSP + bsf SSP1CON2,ACKEN ; Master acknowlegde + bra WaitMSSP ; And return! global I2C_RX_compass I2C_RX_compass: - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3C ; address - rcall I2C_TX - movlw 0x03 + 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 - bsf SSP1CON2,PEN ; Stop condition - rcall WaitMSSP + movlw 0x03 + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP - bcf PIR1,SSPIF - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3D ; address + bcf PIR1,SSPIF + bsf SSP1CON2,SEN ; Start condition + rcall WaitMSSP + movlw 0x3D ; address rcall I2C_TX ; Compass IC sends data in following order: @@ -249,16 +333,16 @@ I2C_RX_compass2: banksel common rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DZ+1; Data Byte + movff SSP1BUF,compass_DZ+1; Data Byte rcall I2C_OneByteRX ; Get one byte - movff SSP1BUF,compass_DZ+0; Data 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 + 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 @@ -269,33 +353,119 @@ 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 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. +I2C_RX_compass1_2: + 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 + rcall WaitMSSP + return global I2C_init_compass I2C_init_compass: - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3C ; address + bsf compass_enabled + 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,SSPIF + 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 +; init compass0 + bsf SSP1CON2,SEN ; Start condition + rcall WaitMSSP + movlw 0x3C ; address rcall I2C_TX - movlw 0x00 + 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 +; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) + movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged rcall I2C_TX bra I2C_init_compass_common global I2C_init_compass_fast I2C_init_compass_fast: - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3C ; address + btfsc compass_type ; compass1? + bra I2C_init_compass_fast1 ; yes +;I2C_init_compass_fast0: + bsf SSP1CON2,SEN ; Start condition + rcall WaitMSSP + movlw 0x3C ; address rcall I2C_TX - movlw 0x00 + movlw 0x00 rcall I2C_TX - movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged -; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) + movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged +; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) rcall I2C_TX I2C_init_compass_common: - movff opt_compass_gain,i2c_temp ; 0-7 (230LSB/Gauss to 1370LSB/Gaus) + movff opt_compass_gain,i2c_temp ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) swapf i2c_temp,F comf i2c_temp,F bcf STATUS,C @@ -303,35 +473,119 @@ movf i2c_temp,W clrf i2c_temp rcall I2C_TX - movlw b'00000000' ; Continous Mode + movlw b'00000000' ; Continous Mode rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - rcall WaitMSSP - bsf compass_enabled + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP 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 + ;movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) + movlw b'00000000' ; CTRL6 (+/-2 Gauss) + rcall I2C_TX + movlw b'00000000' ; CTRL7 Continuous Mode + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP + return + +I2C_init_compass_fast1: + 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'01101111' ; CTRL1 (100Hz, 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'01110100' ; CTRL5 HIGH res, 100Hz + rcall I2C_TX + movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) + rcall I2C_TX + movlw b'00000000' ; CTRL7 Continuous Mode + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP + return + global I2C_sleep_compass I2C_sleep_compass: - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3C ; address - rcall I2C_TX - movlw 0x00 - rcall I2C_TX - movlw b'01101000' ; ConfigA + bcf compass_enabled + + 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 b'00100000' ; ConfigB + movlw 0x00 rcall I2C_TX - movlw b'00000010' ; Idle Mode + movlw b'01101000' ; ConfigA rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - rcall WaitMSSP - bcf compass_enabled + movlw b'00100000' ; ConfigB + rcall I2C_TX + movlw b'00000010' ; Idle Mode + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP 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 + rcall WaitMSSP + return + global I2C_init_accelerometer I2C_init_accelerometer: + 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 @@ -376,6 +630,9 @@ global I2C_sleep_accelerometer I2C_sleep_accelerometer: + btfsc compass_type ; compass1? + return ; yes, ignore + bsf SSP1CON2,SEN ; Start condition rcall WaitMSSP movlw 0x38 ; address @@ -582,7 +839,6 @@ bsf SSP1CON2, RCEN ; Enable recieve mode rcall WaitMSSP return - - - - END \ No newline at end of file + + + END \ No newline at end of file