Mercurial > public > hwos_code
annotate src/i2c.asm @ 498:e8351dd7bb90
compass1 full scale gain test
| author | heinrichsweikamp |
|---|---|
| date | Wed, 19 Apr 2017 12:54:00 +0200 |
| parents | 6ca155fc1509 |
| children | dd28d4efd4d2 |
| rev | line source |
|---|---|
| 0 | 1 ;============================================================================= |
| 2 ; | |
| 3 ; File i2c.asm | |
| 4 ; | |
| 5 ; I2C Interface to HMC5883L and MMA8452Q | |
| 6 ; | |
| 7 ; HMC5883L's read address (8-Bit): 0x3D | |
| 8 ; HMC5883L's write address (8-Bit): 0x3C | |
| 9 ; | |
| 10 ; MMA8452Q's read address (8-Bit): 0x39 | |
| 11 ; MMA8452Q's write address (8-Bit): 0x38 | |
| 12 ; | |
| 427 | 13 ; LSM303D's read address (8-Bit): 0x3D |
| 14 ; LSM303D's write address (8-Bit): 0x3C | |
| 15 ; | |
| 0 | 16 ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. |
| 17 ;============================================================================= | |
| 18 ; HISTORY | |
| 19 ; 2012-08-22 : [mH] Creation | |
| 20 | |
| 21 | |
| 275 | 22 #include "hwos.inc" ; Mandatory header |
| 0 | 23 #include "wait.inc" |
| 113 | 24 #include "math.inc" |
| 25 | |
| 0 | 26 i2c CODE |
| 27 | |
| 28 WaitMSSP: | |
| 29 decfsz i2c_temp,F ; check for timeout during I2C action | |
| 30 bra WaitMSSP2 | |
| 31 bra I2CFail ; timeout occured | |
| 32 WaitMSSP2: | |
| 33 btfss PIR1,SSPIF | |
| 34 bra WaitMSSP | |
| 35 clrf i2c_temp | |
| 36 bcf PIR1,SSPIF | |
| 37 nop | |
| 38 return | |
| 39 | |
| 40 I2C_WaitforACK: | |
| 41 btfss SSPCON2,ACKSTAT ; checks for ACK bit from slave | |
| 42 return | |
| 43 I2CFail: | |
| 44 rcall I2CReset ; I2C Reset | |
| 45 bcf PIR1,SSPIF | |
| 46 clrf i2c_temp | |
| 47 return | |
| 48 | |
| 49 I2CReset: ; Something went wrong (Slave holds SDA low?) | |
| 50 clrf SSP1CON1 ; wake-up slave and reset entire module | |
| 51 clrf SSP1CON2 | |
| 52 clrf SSP1STAT | |
| 53 bcf TRISC,3 ; SCL OUTPUT | |
| 54 bsf TRISC,4 ; SDA Input | |
| 55 bcf PORTC,3 | |
| 56 movlw d'9' | |
| 57 movwf i2c_temp ; clock-out 9 clock cycles manually | |
| 58 I2CReset_1: | |
| 59 bsf PORTC,3 ; SCL=1 | |
| 60 nop | |
| 61 nop | |
| 62 nop | |
| 63 nop | |
| 64 btfsc PORTC,4 ; SDA=1? | |
| 65 bra I2CReset_2 ; =1, SDA has been released from slave | |
| 66 bcf PORTC,3 ; SCL=0 | |
| 67 nop | |
| 68 nop | |
| 69 bcf PORTC,3 | |
| 70 nop | |
| 71 nop | |
| 72 decfsz i2c_temp,F | |
| 73 bra I2CReset_1 ; check for nine clock cycles | |
| 74 I2CReset_2: | |
| 75 bsf TRISC,3 ; SCL Input | |
| 76 clrf SSP1CON1 ; setup I²C Mode | |
| 77 WAITMS d'10' ; Reset-Timeout for I2C devices | |
| 78 movlw b'00000000' ; with slew rate control | |
| 79 movwf SSPSTAT | |
| 80 movlw b'00101000' | |
| 81 movwf SSP1CON1 | |
| 82 movlw b'00000000' | |
| 83 movwf SSP1CON2 | |
| 84 movlw 0x27 | |
| 85 movwf SSP1ADD | |
| 86 return | |
| 87 | |
| 88 I2C_TX: | |
| 89 movwf SSP1BUF | |
| 90 rcall WaitMSSP | |
| 91 bra I2C_WaitforACK ; Returns... | |
| 92 | |
| 93 I2C_TwoBytesRX_div16: ; Get two bytes and devide lo:hi/16 (signed) | |
| 94 rcall I2C_OneByteRX ; Get one byte | |
| 95 movff SSP1BUF,hi ; Data Byte | |
| 96 rcall I2C_OneByteRX ; Get one byte | |
| 97 movff SSP1BUF,lo ; Data Byte | |
| 98 I2C_TwoBytesRX_div16_2: ; devide lo:hi/16 (signed) only | |
| 99 bcf STATUS,C | |
| 100 btfsc hi,7 ; Copy sign bit to carry | |
| 101 bsf STATUS,C | |
| 102 rrcf hi ; /2 | |
| 427 | 103 rrcf lo |
| 104 I2C_TwoBytesRX_div8_2: ; devide lo:hi/8 (signed) only | |
| 0 | 105 bcf STATUS,C |
| 106 btfsc hi,7 ; Copy sign bit to carry | |
| 107 bsf STATUS,C | |
| 108 rrcf hi ; /4 | |
| 427 | 109 rrcf lo |
| 0 | 110 bcf STATUS,C |
| 111 btfsc hi,7 ; Copy sign bit to carry | |
| 112 bsf STATUS,C | |
| 113 rrcf hi ; /8 | |
| 114 rrcf lo | |
| 115 bcf STATUS,C | |
| 116 btfsc hi,7 ; Copy sign bit to carry | |
| 117 bsf STATUS,C | |
| 118 rrcf hi ; /16 | |
| 119 rrcf lo | |
| 120 return | |
| 121 | |
| 122 global I2C_RX_accelerometer | |
| 123 I2C_RX_accelerometer: | |
| 427 | 124 btfsc compass_type ; compass1? |
| 125 bra I2C_RX_accelerometer_compass1 ; yes | |
| 126 ;I2C_RX_accelerometer_compass0: | |
| 127 bsf SSP1CON2,SEN ; Start condition | |
| 128 rcall WaitMSSP | |
| 129 movlw 0x38 ; address | |
| 0 | 130 rcall I2C_TX |
| 427 | 131 movlw 0x00 |
| 0 | 132 rcall I2C_TX |
| 427 | 133 bsf SSP1CON2,RSEN ; Repeated start condition (!) |
| 134 rcall WaitMSSP | |
| 135 movlw 0x39 ; address | |
| 0 | 136 rcall I2C_TX |
| 137 | |
| 158 | 138 rcall I2C_OneByteRX ; Get Status Byte |
| 139 movf SSP1BUF,W | |
| 140 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
141 ; Non-flipped screen: |
| 0 | 142 ; Chip orientation on the PCB requires |
| 143 ; Original = Corrected | |
| 144 ; x = -x | |
| 145 ; y = -y | |
| 146 ; z = -z | |
| 147 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
148 ; Flipped screen: |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
149 ; Chip orientation on the PCB requires |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
150 ; Original = Corrected |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
151 ; x = x |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
152 ; y = y |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
153 ; z = -z |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
154 |
| 0 | 155 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed) |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
156 btfsc flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
157 bra I2C_RX_accelerometer2 ; Yes |
| 0 | 158 comf hi ; 16bit sign change. |
| 159 negf lo | |
| 160 btfsc STATUS,C ; Carry to propagate ? | |
| 161 incf hi,F ; YES: do it. | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
162 I2C_RX_accelerometer2: |
| 0 | 163 movff lo,accel_DX+0 |
| 164 movff hi,accel_DX+1 ; Copy result | |
| 165 | |
| 166 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed) | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
167 btfsc flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
168 bra I2C_RX_accelerometer3 ; Yes |
| 0 | 169 comf hi ; 16bit sign change. |
| 170 negf lo | |
| 171 btfsc STATUS,C ; Carry to propagate ? | |
| 172 incf hi,F ; YES: do it. | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
173 I2C_RX_accelerometer3: |
| 0 | 174 movff lo,accel_DY+0 |
| 175 movff hi,accel_DY+1 ; Copy result | |
| 176 | |
| 177 rcall I2C_OneByteRX ; Get one byte | |
| 178 movff SSP1BUF,hi ; Data Byte | |
| 179 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 180 rcall WaitMSSP | |
| 181 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+0)... | |
| 182 movff SSP1BUF,lo ; Data Byte | |
| 183 | |
| 184 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
| 185 comf hi ; 16bit sign change. | |
| 186 negf lo | |
| 187 btfsc STATUS,C ; Carry to propagate ? | |
| 188 incf hi,F ; YES: do it. | |
| 189 movff lo,accel_DZ+0 | |
| 190 movff hi,accel_DZ+1 ; Copy result | |
| 191 | |
| 192 bsf SSP1CON2,PEN ; Stop condition | |
| 193 rcall WaitMSSP | |
| 194 return | |
| 195 | |
| 427 | 196 I2C_RX_accelerometer_compass1: |
| 197 bsf SSP1CON2,SEN ; Start condition | |
| 198 rcall WaitMSSP | |
| 199 movlw 0x3C ; address | |
| 200 rcall I2C_TX | |
| 201 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) | |
| 202 rcall I2C_TX | |
| 203 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
| 204 rcall WaitMSSP | |
| 205 movlw 0x3D ; address | |
| 206 rcall I2C_TX | |
| 207 | |
| 208 ; Non-flipped screen: | |
| 209 ; Chip orientation on the PCB requires | |
| 210 ; Original = Corrected | |
| 211 ; x = -x | |
| 212 ; y = -y | |
| 213 ; z = -z | |
| 214 | |
| 215 ; Flipped screen: | |
| 216 ; Chip orientation on the PCB requires | |
| 217 ; Original = Corrected | |
| 218 ; x = x | |
| 219 ; y = y | |
| 220 ; z = -z | |
| 221 | |
| 222 ; Dump the accelerator data | |
| 223 rcall I2C_OneByteRX | |
| 224 movff SSP1BUF,lo ;accel_DX+0 | |
| 225 rcall I2C_OneByteRX | |
| 226 movff SSP1BUF,hi ;accel_DX+1 | |
| 227 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
| 228 btfsc flip_screen ; 180° rotation ? | |
| 229 bra I2C_RX_accelerometer2_c1 ; Yes | |
| 230 comf hi ; 16bit sign change. | |
| 231 negf lo | |
| 232 btfsc STATUS,C ; Carry to propagate ? | |
| 233 incf hi,F ; YES: do it. | |
| 234 I2C_RX_accelerometer2_c1: | |
| 235 movff lo,accel_DX+0 | |
| 236 movff hi,accel_DX+1 ; Copy result | |
| 237 | |
| 238 rcall I2C_OneByteRX | |
| 239 movff SSP1BUF,lo ;accel_DY+0 | |
| 240 rcall I2C_OneByteRX | |
| 241 movff SSP1BUF,hi ;accel_DY+1 | |
| 242 | |
| 243 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
| 244 btfsc flip_screen ; 180° rotation ? | |
| 245 bra I2C_RX_accelerometer3_c1 ; Yes | |
| 246 comf hi ; 16bit sign change. | |
| 247 negf lo | |
| 248 btfsc STATUS,C ; Carry to propagate ? | |
| 249 incf hi,F ; YES: do it. | |
| 250 I2C_RX_accelerometer3_c1: | |
| 251 movff lo,accel_DY+0 | |
| 252 movff hi,accel_DY+1 ; Copy result | |
| 253 | |
| 254 rcall I2C_OneByteRX | |
| 255 movff SSP1BUF,lo ;accel_DZ+0 | |
| 256 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 257 rcall WaitMSSP | |
| 258 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+1)... | |
| 259 movff SSP1BUF,hi ;accel_DZ+1 | |
| 260 bsf SSP1CON2,PEN ; Stop condition | |
| 261 rcall WaitMSSP | |
| 262 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
| 263 comf hi ; 16bit sign change for Z | |
| 264 negf lo | |
| 265 btfsc STATUS,C ; Carry to propagate ? | |
| 266 incf hi,F ; YES: do it. | |
| 267 movff lo,accel_DZ+0 | |
| 268 movff hi,accel_DZ+1 ; Copy result | |
| 269 return | |
| 270 | |
| 0 | 271 I2C_OneByteRX: |
| 427 | 272 bsf SSP1CON2, RCEN ; Enable recieve mode |
| 273 rcall WaitMSSP | |
| 274 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 275 bra WaitMSSP ; And return! | |
| 0 | 276 |
| 277 global I2C_RX_compass | |
| 278 I2C_RX_compass: | |
| 427 | 279 btfsc compass_type ; compass1? |
| 280 bra I2C_RX_compass1 ; yes | |
| 281 ;I2C_RX_compass0: | |
| 282 bsf SSP1CON2,SEN ; Start condition | |
| 283 rcall WaitMSSP | |
| 284 movlw 0x3C ; address | |
| 0 | 285 rcall I2C_TX |
| 427 | 286 movlw 0x03 |
| 287 rcall I2C_TX | |
| 288 bsf SSP1CON2,PEN ; Stop condition | |
| 289 rcall WaitMSSP | |
| 0 | 290 |
| 427 | 291 bcf PIR1,SSPIF |
| 292 bsf SSP1CON2,SEN ; Start condition | |
| 293 rcall WaitMSSP | |
| 294 movlw 0x3D ; address | |
| 0 | 295 rcall I2C_TX |
| 296 | |
| 297 ; Compass IC sends data in following order: | |
| 298 ; x MSB | |
| 299 ; x LSB | |
| 300 ; z MSB | |
| 301 ; z LSB | |
| 302 ; y MSB | |
| 303 ; y LSB | |
| 304 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
305 ; Non-flipped screen |
| 0 | 306 ; Chip orientation on the PCB requires |
| 307 ; Original = Corrected | |
| 308 ; x = -y | |
| 309 ; z = z | |
| 310 ; y = x | |
| 311 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
312 ; Flipped screen |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
313 ; Chip orientation on the PCB requires |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
314 ; Original = Corrected |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
315 ; x = y |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
316 ; z = z |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
317 ; y = -x |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
318 |
| 0 | 319 rcall I2C_OneByteRX ; Get one byte |
| 320 movff SSP1BUF,compass_DY+1; Data Byte | |
| 321 rcall I2C_OneByteRX ; Get one byte | |
| 322 movff SSP1BUF,compass_DY+0; Data Byte | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
323 btfsc flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
324 bra I2C_RX_compass2 ; Yes |
| 0 | 325 banksel compass_DY |
| 326 comf compass_DY+1 ; 16bit sign change. | |
| 327 negf compass_DY+0 | |
| 328 btfsc STATUS,C ; Carry to propagate ? | |
| 329 incf compass_DY+1,F ; YES: do it. | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
330 I2C_RX_compass2: |
| 0 | 331 banksel common |
| 332 rcall I2C_OneByteRX ; Get one byte | |
| 427 | 333 movff SSP1BUF,compass_DZ+1; Data Byte |
| 0 | 334 rcall I2C_OneByteRX ; Get one byte |
| 427 | 335 movff SSP1BUF,compass_DZ+0; Data Byte |
| 0 | 336 rcall I2C_OneByteRX ; Get one byte |
| 427 | 337 movff SSP1BUF,compass_DX+1; Data Byte |
| 338 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 339 rcall WaitMSSP | |
| 340 movff SSP1BUF,compass_DX+0; Data Byte | |
| 341 bsf SSP1CON2,PEN ; Stop condition | |
| 342 rcall WaitMSSP | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
343 btfss flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
344 return ; No, done. |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
345 ; Yes, flip X |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
346 banksel compass_DX |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
347 comf compass_DX+1 ; 16bit sign change. |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
348 negf compass_DX+0 |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
349 btfsc STATUS,C ; Carry to propagate ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
350 incf compass_DX+1,F ; YES: do it. |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
351 banksel common |
| 0 | 352 return |
| 427 | 353 |
| 354 I2C_RX_compass1: ; New compass | |
| 355 bsf SSP1CON2,SEN ; Start condition | |
| 356 rcall WaitMSSP | |
| 357 movlw 0x3C ; address | |
| 358 rcall I2C_TX | |
| 359 movlw b'10001000' ; 0x08 with auto-increment (MSB=1) | |
| 360 rcall I2C_TX | |
| 361 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
| 362 rcall WaitMSSP | |
| 363 movlw 0x3D ; address | |
| 364 rcall I2C_TX | |
| 365 | |
| 366 rcall I2C_OneByteRX ; Get one byte | |
| 367 movff SSP1BUF,lo ; Data Byte | |
| 368 rcall I2C_OneByteRX ; Get one byte | |
| 369 movff SSP1BUF,hi ; Data Byte | |
| 370 rcall I2C_TwoBytesRX_div8_2 | |
| 371 movff lo,compass_DX+0 | |
| 372 movff hi,compass_DX+1 | |
| 373 btfss flip_screen ; 180° rotation ? | |
| 374 bra I2C_RX_compass1_1 ; Yes | |
| 375 ; Yes, flip X | |
| 376 banksel compass_DX | |
| 377 comf compass_DX+1 ; 16bit sign change. | |
| 378 negf compass_DX+0 | |
| 379 btfsc STATUS,C ; Carry to propagate ? | |
| 380 incf compass_DX+1,F ; YES: do it. | |
| 381 banksel common | |
| 382 I2C_RX_compass1_1: | |
| 383 rcall I2C_OneByteRX ; Get one byte | |
| 384 movff SSP1BUF,lo ; Data Byte | |
| 385 rcall I2C_OneByteRX ; Get one byte | |
| 386 movff SSP1BUF,hi ; Data Byte | |
| 387 rcall I2C_TwoBytesRX_div8_2 | |
| 388 movff lo,compass_DY+0 | |
| 389 movff hi,compass_DY+1 | |
| 390 btfss flip_screen ; 180° rotation ? | |
| 391 bra I2C_RX_compass1_2 ; Yes | |
| 392 ; Yes, flip Y | |
| 393 banksel compass_DY | |
| 394 comf compass_DY+1 ; 16bit sign change. | |
| 395 negf compass_DY+0 | |
| 396 btfsc STATUS,C ; Carry to propagate ? | |
| 397 incf compass_DY+1,F ; YES: do it. | |
| 398 I2C_RX_compass1_2: | |
| 399 banksel common | |
| 400 rcall I2C_OneByteRX ; Get one byte | |
| 401 movff SSP1BUF,lo ; Data Byte | |
| 402 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 403 rcall WaitMSSP | |
| 404 movff SSP1BUF,hi ; Data Byte | |
| 405 rcall I2C_TwoBytesRX_div8_2 | |
| 406 movff lo,compass_DZ+0 | |
| 407 movff hi,compass_DZ+1 | |
| 408 bsf SSP1CON2,PEN ; Stop condition | |
| 409 rcall WaitMSSP | |
| 410 return | |
| 0 | 411 |
| 412 global I2C_init_compass | |
| 413 I2C_init_compass: | |
| 427 | 414 bsf compass_enabled |
| 415 bsf compass_type ; set flag | |
| 416 bsf SSP1CON2,SEN ; Start condition | |
| 417 rcall WaitMSSP | |
| 418 movlw 0x3C ; address | |
| 419 rcall I2C_TX | |
| 420 movlw 0x0F | |
| 421 rcall I2C_TX | |
| 422 bsf SSP1CON2,PEN ; Stop condition | |
| 423 rcall WaitMSSP | |
| 424 bcf PIR1,SSPIF | |
| 425 bsf SSP1CON2,SEN ; Start condition | |
| 426 rcall WaitMSSP | |
| 427 movlw 0x3D ; address | |
| 428 rcall I2C_TX | |
| 429 rcall I2C_OneByteRX ; Get one byte | |
| 430 movlw 0x49 ; 0x49 = Compass1 | |
| 431 cpfseq SSP1BUF | |
| 432 bcf compass_type ; clear flag | |
| 433 bsf SSP1CON2,PEN ; Stop condition | |
| 434 rcall WaitMSSP | |
| 435 | |
| 436 btfsc compass_type ; compass1? | |
| 437 bra I2C_init_compass1 ; yes | |
| 438 ; init compass0 | |
| 439 bsf SSP1CON2,SEN ; Start condition | |
| 440 rcall WaitMSSP | |
| 441 movlw 0x3C ; address | |
| 0 | 442 rcall I2C_TX |
| 427 | 443 movlw 0x00 |
| 0 | 444 rcall I2C_TX |
| 427 | 445 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) |
| 446 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged | |
| 0 | 447 rcall I2C_TX |
| 20 | 448 bra I2C_init_compass_common |
| 449 | |
| 450 global I2C_init_compass_fast | |
| 451 I2C_init_compass_fast: | |
| 427 | 452 btfsc compass_type ; compass1? |
| 453 bra I2C_init_compass_fast1 ; yes | |
| 454 ;I2C_init_compass_fast0: | |
| 455 bsf SSP1CON2,SEN ; Start condition | |
| 456 rcall WaitMSSP | |
| 457 movlw 0x3C ; address | |
| 20 | 458 rcall I2C_TX |
| 427 | 459 movlw 0x00 |
| 20 | 460 rcall I2C_TX |
| 427 | 461 movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged |
| 462 ; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) | |
| 20 | 463 rcall I2C_TX |
| 464 I2C_init_compass_common: | |
| 427 | 465 movff opt_compass_gain,i2c_temp ; 0-7 (230LSB/Gauss to 1370LSB/Gauss) |
|
18
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
466 swapf i2c_temp,F |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
467 comf i2c_temp,F |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
468 bcf STATUS,C |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
469 rlcf i2c_temp |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
470 movf i2c_temp,W |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
471 clrf i2c_temp |
| 0 | 472 rcall I2C_TX |
| 427 | 473 movlw b'00000000' ; Continous Mode |
| 0 | 474 rcall I2C_TX |
| 427 | 475 bsf SSP1CON2,PEN ; Stop condition |
| 476 rcall WaitMSSP | |
| 0 | 477 return |
| 478 | |
| 427 | 479 I2C_init_compass1: |
| 480 bsf SSP1CON2,SEN ; Start condition | |
| 481 rcall WaitMSSP | |
| 482 movlw 0x3C ; address | |
| 483 rcall I2C_TX | |
| 484 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
| 485 rcall I2C_TX | |
| 486 movlw b'00000000' ; CTRL0 | |
| 487 rcall I2C_TX | |
| 488 movlw b'00101111' ; CTRL1 (6,25Hz, BDU=0, x,y,z = ON) | |
| 489 rcall I2C_TX | |
| 490 movlw b'11000000' ; CTRL2 (50Hz, +/-2g, | |
| 491 rcall I2C_TX | |
| 492 movlw b'00000000' ; CTRL3 | |
| 493 rcall I2C_TX | |
| 494 movlw b'00000000' ; CTRL4 | |
| 495 rcall I2C_TX | |
| 496 movlw b'01100100' ; CTRL5 HIGH res, 6,25Hz | |
| 497 rcall I2C_TX | |
| 429 | 498 init_compass1_common: |
| 498 | 499 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730LSB/Gauss) |
| 448 | 500 ;movlw b'00000000' ; CTRL6 (+/-2 Gauss) |
| 498 | 501 ;movlw b'00100000' ; CTRL6 (+/-4 Gauss) |
| 427 | 502 rcall I2C_TX |
| 503 movlw b'00000000' ; CTRL7 Continuous Mode | |
| 504 rcall I2C_TX | |
| 505 bsf SSP1CON2,PEN ; Stop condition | |
| 506 rcall WaitMSSP | |
| 507 return | |
| 508 | |
| 509 I2C_init_compass_fast1: | |
| 510 bsf SSP1CON2,SEN ; Start condition | |
| 511 rcall WaitMSSP | |
| 512 movlw 0x3C ; address | |
| 513 rcall I2C_TX | |
| 514 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
| 515 rcall I2C_TX | |
| 516 movlw b'00000000' ; CTRL0 | |
| 517 rcall I2C_TX | |
| 518 movlw b'01101111' ; CTRL1 (100Hz, BDU=0, x,y,z = ON) | |
| 519 rcall I2C_TX | |
| 520 movlw b'11000000' ; CTRL2 (50Hz, +/-2g, | |
| 521 rcall I2C_TX | |
| 522 movlw b'00000000' ; CTRL3 | |
| 523 rcall I2C_TX | |
| 524 movlw b'00000000' ; CTRL4 | |
| 525 rcall I2C_TX | |
| 526 movlw b'01110100' ; CTRL5 HIGH res, 100Hz | |
| 527 rcall I2C_TX | |
| 429 | 528 bra init_compass1_common |
| 427 | 529 |
| 0 | 530 global I2C_sleep_compass |
| 531 I2C_sleep_compass: | |
| 427 | 532 bcf compass_enabled |
| 533 | |
| 534 btfsc compass_type ; compass1? | |
| 535 bra I2C_sleep_compass1 ; yes | |
| 536 ;I2C_sleep_compass0: | |
| 537 bsf SSP1CON2,SEN ; Start condition | |
| 538 rcall WaitMSSP | |
| 539 movlw 0x3C ; address | |
| 0 | 540 rcall I2C_TX |
| 427 | 541 movlw 0x00 |
| 0 | 542 rcall I2C_TX |
| 427 | 543 movlw b'01101000' ; ConfigA |
| 0 | 544 rcall I2C_TX |
| 427 | 545 movlw b'00100000' ; ConfigB |
| 546 rcall I2C_TX | |
| 547 movlw b'00000010' ; Idle Mode | |
| 548 rcall I2C_TX | |
| 549 bsf SSP1CON2,PEN ; Stop condition | |
| 550 rcall WaitMSSP | |
| 0 | 551 return |
| 552 | |
| 427 | 553 I2C_sleep_compass1: |
| 554 bsf SSP1CON2,SEN ; Start condition | |
| 555 rcall WaitMSSP | |
| 556 movlw 0x3C ; address | |
| 557 rcall I2C_TX | |
| 558 movlw 0x20 ; CTRL_REG1 | |
| 559 rcall I2C_TX | |
| 560 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor Power-down mode | |
| 561 rcall I2C_TX | |
| 562 bsf SSP1CON2,PEN ; Stop condition | |
| 563 rcall WaitMSSP | |
| 564 bsf SSP1CON2,SEN ; Start condition | |
| 565 rcall WaitMSSP | |
| 566 movlw 0x3C ; address | |
| 567 rcall I2C_TX | |
| 568 movlw 0x26 ; CTRL_REG7 | |
| 569 rcall I2C_TX | |
| 570 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor Power-down mode | |
| 571 rcall I2C_TX | |
| 572 bsf SSP1CON2,PEN ; Stop condition | |
| 573 rcall WaitMSSP | |
| 574 return | |
| 575 | |
| 0 | 576 |
| 577 global I2C_init_accelerometer | |
| 578 I2C_init_accelerometer: | |
| 427 | 579 btfsc compass_type ; compass1? |
| 580 return ; yes, ignore | |
| 581 | |
| 0 | 582 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode |
| 583 | |
| 584 bsf SSP1CON2,SEN ; Start condition | |
| 585 rcall WaitMSSP | |
| 586 movlw 0x38 ; address | |
| 587 rcall I2C_TX | |
| 588 movlw 0x0E ; XYZ_DATA_CFG | |
| 589 rcall I2C_TX | |
| 590 movlw b'00000000' ; High pass Filter=0 , +/- 2g range | |
| 591 rcall I2C_TX | |
| 592 bsf SSP1CON2,PEN ; Stop condition | |
| 593 rcall WaitMSSP | |
| 594 | |
| 595 | |
| 596 bsf SSP1CON2,SEN ; Start condition | |
| 597 rcall WaitMSSP | |
| 598 movlw 0x38 ; address | |
| 599 rcall I2C_TX | |
| 600 movlw 0x2A ; CTRL_REG1 | |
| 601 rcall I2C_TX | |
| 602 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode | |
| 603 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode | |
| 604 rcall I2C_TX | |
| 605 movlw b'00000010' ; CTRL_REG2: High Res in Active mode | |
| 606 rcall I2C_TX | |
| 607 bsf SSP1CON2,PEN ; Stop condition | |
| 608 rcall WaitMSSP | |
| 609 | |
| 610 bsf SSP1CON2,SEN ; Start condition | |
| 611 rcall WaitMSSP | |
| 612 movlw 0x38 ; address | |
| 613 rcall I2C_TX | |
| 614 movlw 0x2A ; CTRL_REG1 | |
| 615 rcall I2C_TX | |
| 616 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode | |
| 617 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode | |
| 618 rcall I2C_TX | |
| 619 bsf SSP1CON2,PEN ; Stop condition | |
| 620 rcall WaitMSSP | |
| 621 | |
| 622 return | |
| 623 | |
| 624 global I2C_sleep_accelerometer | |
| 625 I2C_sleep_accelerometer: | |
| 427 | 626 btfsc compass_type ; compass1? |
| 627 return ; yes, ignore | |
| 628 | |
| 0 | 629 bsf SSP1CON2,SEN ; Start condition |
| 630 rcall WaitMSSP | |
| 631 movlw 0x38 ; address | |
| 632 rcall I2C_TX | |
| 633 movlw 0x2A ; CTRL_REG1 | |
| 634 rcall I2C_TX | |
| 635 movlw b'00000000' ; St. By Mode | |
| 636 rcall I2C_TX | |
| 637 bsf SSP1CON2,PEN ; Stop condition | |
| 638 rcall WaitMSSP | |
| 639 return | |
| 640 | |
| 113 | 641 global lt2942_init |
| 642 lt2942_init: ; Setup Control register B | |
| 643 clrf i2c_temp | |
| 644 movlw 0x01 ; Point to control reg B | |
| 467 | 645 rcall I2C_TX_GAUGE |
| 646 movlw b'11111000' ; Automatic conversion every two seconds | |
| 113 | 647 movff WREG, SSP1BUF ; Data Byte |
| 648 rcall WaitMSSP | |
| 649 rcall I2C_WaitforACK | |
| 650 bsf SSP1CON2,PEN ; Stop condition | |
| 467 | 651 bra WaitMSSP ; (And return) |
| 113 | 652 |
| 653 global lt2942_get_status | |
| 654 lt2942_get_status: ; Read status register | |
| 448 | 655 bcf battery_gauge_available ; Clear flag |
| 113 | 656 clrf i2c_temp |
| 657 movlw 0x00 ; Point to Status reg | |
| 467 | 658 rcall I2C_TX_GAUGE |
| 659 rcall I2C_RX_GAUGE | |
| 113 | 660 movff SSP1BUF,WREG |
| 467 | 661 btfss WREG,7 ; 2942 found? |
| 662 bsf battery_gauge_available ; Yes, set flag | |
| 663 bsf SSP1CON2,PEN ; Stop condition | |
| 664 bra WaitMSSP ; (And return) | |
| 113 | 665 |
| 666 | |
| 667 global lt2942_get_voltage | |
| 668 lt2942_get_voltage: ; Read battery voltage registers | |
| 669 clrf i2c_temp | |
| 670 movlw 0x08 ; Point to voltage registers | |
| 448 | 671 rcall I2C_TX_GAUGE |
| 672 rcall I2C_RX_GAUGE | |
| 113 | 673 bsf SSP1CON2,ACKEN ; Master acknowlegde |
| 674 rcall WaitMSSP | |
| 675 movff SSP1BUF,xA+1 | |
| 676 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 677 rcall WaitMSSP | |
| 678 movff SSP1BUF,xA+0 | |
| 679 bsf SSP1CON2,PEN ; Stop condition | |
| 680 rcall WaitMSSP | |
| 681 | |
| 682 ; banksel common | |
| 683 ; xA:2 loaded with raw values | |
| 684 movlw LOW .6000 | |
| 685 movwf xB+0 | |
| 686 movlw HIGH .6000 | |
| 687 movwf xB+1 | |
| 688 call mult16x16 ;xA*xB=xC | |
| 689 | |
| 690 ; devide xC (32bit)/65535 for result in mV (16bit) | |
| 691 movlw .16 | |
| 692 movwf i2c_temp | |
| 693 lt2942_get_voltage2: | |
| 694 bcf STATUS,C | |
| 695 rrcf xC+3,F | |
| 696 rrcf xC+2,F | |
| 697 rrcf xC+1,F | |
| 698 rrcf xC+0,F | |
| 699 decfsz i2c_temp,F | |
| 700 bra lt2942_get_voltage2 | |
| 701 | |
| 702 ; Update battery voltage in mV | |
| 703 movff xC+1,batt_voltage+1 | |
| 704 movff xC+0,batt_voltage+0 | |
| 466 | 705 |
| 706 tstfsz batt_voltage+1 ; <256mV? | |
| 707 return ; No, done. | |
| 708 | |
| 709 rcall lt2942_init | |
| 710 return | |
| 113 | 711 |
| 712 ; global lt2942_get_temperature | |
| 713 ;lt2942_get_temperature: ; Read temperature registers | |
| 714 ; clrf i2c_temp | |
| 715 ; movlw 0x0C ; Point to temperature registers | |
| 716 ; call I2C_TX_GAUGE | |
| 717 ; call I2C_RX | |
| 718 ; bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 719 ; rcall WaitMSSP | |
| 720 ; movff SSP1BUF,xA+1 | |
| 721 ; bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 722 ; rcall WaitMSSP | |
| 723 ; movff SSP1BUF,xA+0 | |
| 724 ; bsf SSP1CON2,PEN ; Stop condition | |
| 725 ; rcall WaitMSSP | |
| 726 ; | |
| 727 ;; banksel common | |
| 728 ; ; xA:2 loaded with raw values | |
| 729 ; movlw LOW .6000 | |
| 730 ; movwf xB+0 | |
| 731 ; movlw HIGH .6000 | |
| 732 ; movwf xB+1 | |
| 733 ; call mult16x16 ;xA*xB=xC | |
| 734 ; | |
| 735 ; ; devide xC (32bit)/65535 for result in 0.1K (16bit) | |
| 736 ; movlw .16 | |
| 737 ; movwf i2c_temp | |
| 738 ;lt2942_get_temperature2: | |
| 739 ; bcf STATUS,C | |
| 740 ; rrcf xC+3,F | |
| 741 ; rrcf xC+2,F | |
| 742 ; rrcf xC+1,F | |
| 743 ; rrcf xC+0,F | |
| 744 ; decfsz i2c_temp,F | |
| 745 ; bra lt2942_get_temperature2 | |
| 746 ; | |
| 747 ; movff xC+1,sub_a+1 | |
| 748 ; movff xC+0,sub_a+0 | |
| 749 ; movlw LOW .2731 ; Kelvin to Celcius offset | |
| 750 ; movwf sub_b+0 | |
| 751 ; movlw HIGH .2731 ; Kelvin to Celcius offset | |
| 752 ; movwf sub_b+1 | |
| 753 ; call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) | |
| 754 ; | |
| 755 ; ; Update batttery_temperature in 0.1°C | |
| 756 ; movff sub_c+1,battery_temperature+1 | |
| 757 ; movff sub_c+0,battery_temperature+0 | |
| 758 ; return | |
| 759 | |
| 760 global lt2942_get_accumulated_charge | |
| 761 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent | |
| 762 clrf i2c_temp | |
| 466 | 763 movlw 0x00 ; Point to status register |
| 467 | 764 rcall I2C_TX_GAUGE |
| 765 rcall I2C_RX_GAUGE | |
| 466 | 766 bsf SSP1CON2,ACKEN ; Master acknowlegde |
| 113 | 767 rcall WaitMSSP |
| 466 | 768 movff SSP1BUF,gauge_status_byte |
| 769 | |
| 770 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 771 rcall WaitMSSP ; Dummy read (Control byte) | |
| 467 | 772 movf SSP1BUF,W |
| 773 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 774 rcall WaitMSSP | |
| 466 | 775 |
| 776 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 113 | 777 rcall WaitMSSP |
| 466 | 778 movff SSP1BUF,sub_a+1 |
| 467 | 779 bsf SSP1CON2,ACKEN ; Master acknowlegde |
| 780 rcall WaitMSSP | |
| 466 | 781 |
| 782 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 783 rcall WaitMSSP | |
| 784 movff SSP1BUF,sub_a+0 | |
| 785 bsf SSP1CON2,PEN ; Stop condition | |
| 113 | 786 rcall WaitMSSP |
| 466 | 787 |
| 788 movff gauge_status_byte,sub_b+0 ; copy into bank common | |
| 789 btfsc sub_b+0,0 ; =1: UVLO Event | |
| 790 rcall lt2942_init | |
| 113 | 791 |
| 466 | 792 movff sub_a+1,battery_acumulated_charge+1 ; Save raw value |
| 793 movff sub_a+0,battery_acumulated_charge+0 ; Save raw value | |
| 794 | |
| 113 | 795 ; Compute batt_percent |
| 211 | 796 ; (charge-battery_offset)/365 |
| 448 | 797 movff battery_offset+0,sub_b+0 |
| 798 movff battery_offset+1,sub_b+1 | |
| 113 | 799 call subU16 ; sub_c = sub_a - sub_b (with signed values) |
| 800 | |
| 801 clrf batt_percent ; Set to zero | |
| 802 btfsc neg_flag ; result negative? | |
| 449 | 803 bra lt2942_set_to_zero_percent ; Yes, keep LT2942 at zero percent and return |
| 113 | 804 |
| 805 ; > Zero, set batt_percent properly | |
| 806 movff sub_c+0,xA+0 | |
| 807 movff sub_c+1,xA+1 | |
| 448 | 808 movff battery_capacity+0,xB+0 |
| 809 movff battery_capacity+1,xB+1 | |
| 113 | 810 call div16x16 ;xA/xB=xC with xA+0 as remainder, uses divB as temp variable |
| 811 movff xC+0,batt_percent | |
| 812 return | |
| 813 | |
| 449 | 814 lt2942_set_to_zero_percent: |
| 815 clrf i2c_temp | |
| 816 movlw 0x02 ; Point to accumulated charge registers | |
| 817 rcall I2C_TX_GAUGE | |
| 818 movff battery_offset+1,SSP1BUF | |
| 819 rcall WaitMSSP | |
| 820 rcall I2C_WaitforACK | |
| 821 movff battery_offset+0,SSP1BUF | |
| 822 rcall WaitMSSP | |
| 823 rcall I2C_WaitforACK | |
| 824 bsf SSP1CON2,PEN ; Stop condition | |
| 825 bra WaitMSSP; (and return) | |
| 826 | |
| 113 | 827 global lt2942_charge_done |
| 828 lt2942_charge_done: ; Reset accumulating registers to 0xFFFF | |
| 829 clrf i2c_temp | |
| 830 movlw 0x02 ; Point to accumulated charge registers | |
| 448 | 831 rcall I2C_TX_GAUGE |
| 832 setf SSP1BUF ; Data Byte | |
| 113 | 833 rcall WaitMSSP |
| 834 rcall I2C_WaitforACK | |
| 448 | 835 setf SSP1BUF ; Data Byte |
| 113 | 836 rcall WaitMSSP |
| 837 rcall I2C_WaitforACK | |
| 448 | 838 bsf SSP1CON2,PEN ; Stop condition |
| 839 bra WaitMSSP; (and return) | |
| 113 | 840 |
| 841 I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC | |
| 842 movwf i2c_temp+1 ; Data byte | |
| 448 | 843 bsf SSP1CON2,SEN ; Start condition |
| 113 | 844 rcall WaitMSSP |
| 845 movlw b'11001000' ; Address byte + Write bit | |
| 846 movwf SSP1BUF ; control byte | |
| 847 rcall WaitMSSP | |
| 848 rcall I2C_WaitforACK | |
| 849 movff i2c_temp+1, SSP1BUF ; Data Byte | |
| 850 rcall WaitMSSP | |
| 448 | 851 bra I2C_WaitforACK ; (and return) |
| 113 | 852 |
| 853 I2C_RX_GAUGE: | |
| 854 bsf SSP1CON2,SEN ; Start condition | |
| 855 rcall WaitMSSP | |
| 856 movlw b'11001001' ; Address byte + Read bit | |
| 857 movwf SSP1BUF ; control byte | |
| 858 rcall WaitMSSP | |
| 859 rcall I2C_WaitforACK | |
| 467 | 860 bsf SSP1CON2, RCEN ; Enable recieve mode |
| 448 | 861 bra WaitMSSP; (and return) |
| 427 | 862 |
| 448 | 863 END |
