Mercurial > public > hwos_code
annotate src/i2c.asm @ 624:7bdcc591196c
Support for Compass3 hardware
| author | heinrichsweikamp |
|---|---|
| date | Thu, 13 Jun 2019 10:07:55 +0200 |
| parents | c40025d8e750 |
| children | bf5fee575701 |
| rev | line source |
|---|---|
| 0 | 1 ;============================================================================= |
| 2 ; | |
| 623 | 3 ; File i2c.asm combined next generation V3.03.2 |
| 0 | 4 ; |
| 560 | 5 ; I2C Interface |
| 6 ; | |
| 0 | 7 ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved. |
| 8 ;============================================================================= | |
| 582 | 9 ; |
| 10 ; Compass0 | |
| 11 ; -------- | |
| 12 ; HMC5883L's read address (8-Bit): 0x3D | |
| 13 ; HMC5883L's write address (8-Bit): 0x3C | |
| 14 ; MMA8452Q's read address (8-Bit): 0x39 | |
| 15 ; MMA8452Q's write address (8-Bit): 0x38 | |
| 16 ; | |
| 17 ; Compass1 | |
| 18 ; -------- | |
| 19 ; LSM303D's read address (8-Bit): 0x3D | |
| 20 ; LSM303D's write address (8-Bit): 0x3C | |
| 21 ; | |
| 22 ; Compass2 | |
| 23 ; -------- | |
| 24 ; LSM303AGR's Compass read address (8-Bit): 0x3D | |
| 25 ; LSM303AGR's Compass write address (8-Bit): 0x3C | |
| 26 ; LSM303AGR's Acceleration read address (8-Bit): 0x33 | |
| 27 ; LSM303AGR's Acceleration write address (8-Bit): 0x32 | |
| 624 | 28 ; |
| 29 ; Compass3 | |
| 30 ; -------- | |
| 31 ; LSM303C's Compass read address (8-Bit): 0x3D | |
| 32 ; LSM303C's Compass write address (8-Bit): 0x3C | |
| 33 ; LSM303C's Acceleration read address (8-Bit): 0x3B | |
| 34 ; LSM303C's Acceleration write address (8-Bit): 0x3A | |
| 582 | 35 ; |
| 36 ; RX Circuity | |
| 37 ; ----------- | |
| 38 ; RX Circuity read address (8-Bit): 0x51 | |
| 39 ; RX Circuity write address (8-Bit): 0x50 | |
| 40 ; | |
| 41 ; | |
| 42 | |
| 0 | 43 ; HISTORY |
| 44 ; 2012-08-22 : [mH] Creation | |
| 565 | 45 ; 2018-02-18 : [mH] Sync with hwOS Sport release |
| 0 | 46 |
| 47 | |
| 582 | 48 #include "hwos.inc" ; Mandatory header |
| 0 | 49 #include "wait.inc" |
| 113 | 50 #include "math.inc" |
| 560 | 51 #include "external_flash.inc" |
| 113 | 52 |
| 582 | 53 |
| 623 | 54 i2c CODE |
| 582 | 55 |
| 56 ;============================================================================= | |
| 0 | 57 |
| 58 I2C_TX: | |
| 582 | 59 movwf SSP1BUF |
| 60 rcall WaitMSSP | |
| 604 | 61 bra I2C_WaitforACK ; returns... |
| 0 | 62 |
| 604 | 63 I2C_TwoBytesRX_div16: ; get two bytes and divide lo:hi/16 (signed) |
| 64 rcall I2C_OneByteRX ; get one byte | |
| 65 movff SSP1BUF,hi ; data byte | |
| 66 rcall I2C_OneByteRX ; get one byte | |
| 67 movff SSP1BUF,lo ; data byte | |
| 582 | 68 I2C_TwoBytesRX_div16_2: ; divide lo:hi/16 (signed) only |
| 69 bcf STATUS,C | |
| 604 | 70 btfsc hi,7 ; copy sign bit to carry |
| 582 | 71 bsf STATUS,C |
| 72 rrcf hi ; /2 | |
| 73 rrcf lo | |
| 74 I2C_TwoBytesRX_div8_2: ; divide lo:hi/8 (signed) only | |
| 75 bcf STATUS,C | |
| 604 | 76 btfsc hi,7 ; copy sign bit to carry |
| 582 | 77 bsf STATUS,C |
| 78 rrcf hi ; /4 | |
| 79 rrcf lo | |
| 80 bcf STATUS,C | |
| 604 | 81 btfsc hi,7 ; copy sign bit to carry |
| 582 | 82 bsf STATUS,C |
| 83 rrcf hi ; /8 | |
| 84 rrcf lo | |
| 85 bcf STATUS,C | |
| 604 | 86 btfsc hi,7 ; copy sign bit to carry |
| 582 | 87 bsf STATUS,C |
| 88 rrcf hi ; /16 | |
| 89 rrcf lo | |
| 90 return | |
| 0 | 91 |
| 582 | 92 global I2C_RX_accelerometer |
| 0 | 93 I2C_RX_accelerometer: |
| 624 | 94 btfsc compass_type3 ; compass3 |
| 95 bra I2C_RX_accelerometer_compass3 ; yes | |
| 604 | 96 btfsc compass_type2 ; compass2 ? |
| 97 bra I2C_RX_accelerometer_compass2 ; YES | |
| 98 btfsc compass_type ; compass1 ? | |
| 99 bra I2C_RX_accelerometer_compass1 ; YES | |
| 560 | 100 I2C_RX_accelerometer_compass0: |
| 604 | 101 bsf SSP1CON2,SEN ; start condition |
| 582 | 102 rcall WaitMSSP |
| 103 movlw 0x38 ; address | |
| 104 rcall I2C_TX | |
| 105 movlw 0x00 | |
| 106 rcall I2C_TX | |
| 604 | 107 bsf SSP1CON2,RSEN ; repeated start condition |
| 582 | 108 rcall WaitMSSP |
| 109 movlw 0x39 ; address | |
| 110 rcall I2C_TX | |
| 0 | 111 |
| 604 | 112 rcall I2C_OneByteRX ; get status byte |
| 582 | 113 movf SSP1BUF,W |
| 158 | 114 |
| 582 | 115 ; Non-flipped screen: |
| 116 ; Chip orientation on the PCB requires | |
| 604 | 117 ; Original = corrected |
| 582 | 118 ; x = -x |
| 119 ; y = -y | |
| 120 ; z = -z | |
| 0 | 121 |
| 582 | 122 ; Flipped screen: |
| 123 ; Chip orientation on the PCB requires | |
| 604 | 124 ; Original = corrected |
| 582 | 125 ; x = x |
| 126 ; y = y | |
| 127 ; z = -z | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
128 |
| 604 | 129 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
| 623 | 130 btfsc flip_screen ; 180° rotation? |
| 604 | 131 bra I2C_RX_accelerometer2 ; YES |
| 132 comf hi ; 16 bit sign change | |
| 582 | 133 negf lo |
| 623 | 134 btfsc STATUS,C ; carry to propagate? |
| 604 | 135 incf hi,F ; YES - do it |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
136 I2C_RX_accelerometer2: |
| 623 | 137 MOVII mpr,accel_DX ; copy result |
| 138 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) | |
| 139 btfsc flip_screen ; 180° rotation? | |
| 140 bra I2C_RX_accelerometer3 ; YES | |
| 141 comf hi ; 16 bit sign change | |
| 582 | 142 negf lo |
| 623 | 143 btfsc STATUS,C ; carry to propagate? |
| 144 incf hi,F ; YES - do it | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
145 I2C_RX_accelerometer3: |
| 623 | 146 MOVII mpr,accel_DY ; copy result |
| 147 rcall I2C_OneByteRX ; get one byte | |
| 148 movff SSP1BUF,hi ; data byte | |
| 582 | 149 bsf SSP1CON2, RCEN ; Enable receive mode |
| 150 rcall WaitMSSP | |
| 623 | 151 ; According to data sheet there should be no master Acknowledge for the last byte (accel_DZ+0)... |
| 152 movff SSP1BUF,lo ; data byte | |
| 0 | 153 |
| 582 | 154 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only |
| 623 | 155 comf hi ; 16 bit sign change |
| 582 | 156 negf lo |
| 623 | 157 btfsc STATUS,C ; carry to propagate? |
| 158 incf hi,F ; YES - do it | |
| 159 MOVII mpr,accel_DZ ; copy result | |
| 160 bsf SSP1CON2,PEN ; stop condition | |
| 161 bra WaitMSSP ; ... and return | |
| 0 | 162 |
| 427 | 163 I2C_RX_accelerometer_compass1: |
| 623 | 164 bsf SSP1CON2,SEN ; start condition |
| 582 | 165 rcall WaitMSSP |
| 166 movlw 0x3C ; address | |
| 167 rcall I2C_TX | |
| 168 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) | |
| 169 rcall I2C_TX | |
| 623 | 170 bsf SSP1CON2,RSEN ; repeated start condition (!) |
| 582 | 171 rcall WaitMSSP |
| 172 movlw 0x3D ; address | |
| 624 | 173 I2C_RX_accelerometer_compass1_xx: ; compass2 and 3 continue here... |
| 582 | 174 rcall I2C_TX |
| 175 | |
| 176 ; Non-flipped screen: | |
| 177 ; Chip orientation on the PCB requires | |
| 178 ; Original = Corrected | |
| 179 ; x = -x (Compass 1) | |
| 180 ; x = x (Compass 2) | |
| 181 ; y = -y | |
| 182 ; z = -z | |
| 183 | |
| 184 ; Flipped screen: | |
| 185 ; Chip orientation on the PCB requires | |
| 186 ; Original = Corrected | |
| 187 ; x = x (Compass 1) | |
| 188 ; x = -x (Compass 2) | |
| 189 ; y = y | |
| 190 ; z = -z | |
| 427 | 191 |
| 582 | 192 ; Dump the accelerator data |
| 193 rcall I2C_OneByteRX | |
| 194 movff SSP1BUF,lo ; accel_DX+0 | |
| 195 rcall I2C_OneByteRX | |
| 623 | 196 movff SSP1BUF,hi ; accel_DX+1 |
| 582 | 197 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only |
| 198 btfss compass_type2 ; compass 2? | |
| 623 | 199 bra I2C_RX_accelerometer1_c1 ; NO - compass 1 |
| 582 | 200 ; compass 2 |
| 623 | 201 btfss flip_screen ; 180° rotation? |
| 202 bra I2C_RX_accelerometer2_c1 ; NO - continue with normal compass1 routines for Y and Z | |
| 582 | 203 ; flipped compass 2, negate x |
| 623 | 204 comf hi ; 16 bit sign change |
| 582 | 205 negf lo |
| 623 | 206 btfsc STATUS,C ; carry to propagate? |
| 207 incf hi,F ; YES - do it | |
| 582 | 208 bra I2C_RX_accelerometer2_c1 ; continue with normal compass1 routines for Y and Z |
| 209 | |
| 210 I2C_RX_accelerometer1_c1: | |
| 623 | 211 btfsc flip_screen ; 180° rotation? |
| 212 bra I2C_RX_accelerometer2_c1 ; YES | |
| 582 | 213 ; non-flipped compass 1, negate x |
| 623 | 214 comf hi ; 16 bit sign change |
| 582 | 215 negf lo |
| 623 | 216 btfsc STATUS,C ; carry to propagate? |
| 217 incf hi,F ; YES - do it | |
| 427 | 218 I2C_RX_accelerometer2_c1: |
| 582 | 219 ; flipped compass 1, non-flipped compass 2 |
| 623 | 220 MOVII mpr,accel_DX ; copy result |
| 582 | 221 rcall I2C_OneByteRX |
| 222 movff SSP1BUF,lo ; accel_DY+0 | |
| 223 rcall I2C_OneByteRX | |
| 224 movff SSP1BUF,hi ; accel_DY+1 | |
| 225 | |
| 226 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only | |
| 623 | 227 btfsc flip_screen ; 180° rotation? |
| 228 bra I2C_RX_accelerometer3_c1 ; YES | |
| 229 comf hi ; 16 bit sign change | |
| 582 | 230 negf lo |
| 623 | 231 btfsc STATUS,C ; carry to propagate? |
| 232 incf hi,F ; YES - do it | |
| 427 | 233 I2C_RX_accelerometer3_c1: |
| 623 | 234 MOVII mpr,accel_DY ; copy result |
| 582 | 235 rcall I2C_OneByteRX |
| 623 | 236 movff SSP1BUF,lo ; accel_DZ+0 |
| 582 | 237 bsf SSP1CON2, RCEN ; Enable receive mode |
| 238 rcall WaitMSSP | |
| 623 | 239 ; According to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)... |
| 240 movff SSP1BUF,hi ; accel_DZ+1 | |
| 241 bsf SSP1CON2,PEN ; stop condition | |
| 582 | 242 rcall WaitMSSP |
| 243 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only | |
| 623 | 244 comf hi ; 16 bit sign change for Z |
| 582 | 245 negf lo |
| 623 | 246 btfsc STATUS,C ; carry to propagate? |
| 247 incf hi,F ; YES - do it | |
| 248 MOVII mpr,accel_DZ ; copy result | |
| 582 | 249 return |
| 250 | |
| 560 | 251 I2C_RX_accelerometer_compass2: |
| 623 | 252 bsf SSP1CON2,SEN ; start condition |
| 582 | 253 rcall WaitMSSP |
| 254 movlw 0x32 ; address | |
| 255 rcall I2C_TX | |
| 256 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) | |
| 257 rcall I2C_TX | |
| 623 | 258 bsf SSP1CON2,RSEN ; repeated start condition (!) |
| 582 | 259 rcall WaitMSSP |
| 260 movlw 0x33 ; address | |
| 624 | 261 bra I2C_RX_accelerometer_compass1_xx |
| 262 | |
| 263 I2C_RX_accelerometer_compass3: | |
| 264 bsf SSP1CON2,SEN ; Start condition | |
| 265 rcall WaitMSSP | |
| 266 movlw 0x3A ; address | |
| 267 rcall I2C_TX | |
| 268 movlw 0x28 ; 0x28 (OUT_X_L_A) | |
| 269 rcall I2C_TX | |
| 270 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
| 271 rcall WaitMSSP | |
| 272 movlw 0x3B ; address | |
| 273 bra I2C_RX_accelerometer_compass1_xx | |
| 582 | 274 |
| 0 | 275 I2C_OneByteRX: |
| 623 | 276 bsf SSP1CON2,RCEN ; enable receive mode |
| 582 | 277 rcall WaitMSSP |
| 623 | 278 bsf SSP1CON2,ACKEN ; master acknowledge |
| 279 bra WaitMSSP ; ... and return | |
| 280 | |
| 281 | |
| 282 ;----------------------------------------------------------------------------- | |
| 283 IFDEF _compass | |
| 0 | 284 |
| 582 | 285 global I2C_RX_compass |
| 0 | 286 I2C_RX_compass: |
| 624 | 287 btfsc compass_type3 ; compass3 |
| 288 bra I2C_RX_compass3 ; YES | |
| 623 | 289 btfsc compass_type2 ; compass2 ? |
| 290 bra I2C_RX_compass2 ; YES | |
| 291 btfsc compass_type ; compass1 ? | |
| 292 bra I2C_RX_compass1 ; YES | |
| 560 | 293 I2C_RX_compass0: |
| 623 | 294 bsf SSP1CON2,SEN ; start condition |
| 582 | 295 rcall WaitMSSP |
| 296 movlw 0x3C ; address | |
| 297 rcall I2C_TX | |
| 298 movlw 0x03 | |
| 299 rcall I2C_TX | |
| 623 | 300 bsf SSP1CON2,PEN ; stop condition |
| 582 | 301 rcall WaitMSSP |
| 0 | 302 |
| 582 | 303 bcf PIR1,SSP1IF |
| 623 | 304 bsf SSP1CON2,SEN ; start condition |
| 582 | 305 rcall WaitMSSP |
| 306 movlw 0x3D ; address | |
| 307 rcall I2C_TX | |
| 0 | 308 |
| 582 | 309 ; Compass IC sends data in following order: |
| 310 ; x MSB | |
| 311 ; x LSB | |
| 312 ; z MSB | |
| 313 ; z LSB | |
| 314 ; y MSB | |
| 315 ; y LSB | |
| 0 | 316 |
| 582 | 317 ; Non-flipped screen |
| 318 ; Chip orientation on the PCB requires | |
| 319 ; Original = Corrected | |
| 320 ; x = -y | |
| 321 ; z = z | |
| 322 ; y = x | |
| 0 | 323 |
| 582 | 324 ; Flipped screen |
| 325 ; Chip orientation on the PCB requires | |
| 326 ; Original = Corrected | |
| 327 ; x = y | |
| 328 ; z = z | |
| 329 ; y = -x | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
330 |
| 623 | 331 rcall I2C_OneByteRX ; get one byte |
| 332 movff SSP1BUF,compass_DY+1 ; data byte | |
| 333 rcall I2C_OneByteRX ; get one byte | |
| 334 movff SSP1BUF,compass_DY+0 ; data byte | |
| 335 btfsc flip_screen ; 180° rotation? | |
| 336 bra I2C_RX_compass0_2 ; NO | |
| 337 banksel compass_DY ; YES - flip Y | |
| 338 comf compass_DY+1 ; - 16 bit sign change | |
| 582 | 339 negf compass_DY+0 |
| 623 | 340 btfsc STATUS,C ; - carry to propagate? |
| 341 incf compass_DY+1,F ; YES - do it | |
| 582 | 342 banksel common |
| 623 | 343 I2C_RX_compass0_2: |
| 344 rcall I2C_OneByteRX ; get one byte | |
| 345 movff SSP1BUF,compass_DZ+1 ; data byte | |
| 346 rcall I2C_OneByteRX ; get one byte | |
| 347 movff SSP1BUF,compass_DZ+0 ; data byte | |
| 348 rcall I2C_OneByteRX ; get one byte | |
| 349 movff SSP1BUF,compass_DX+1 ; data byte | |
| 582 | 350 bsf SSP1CON2, RCEN ; Enable receive mode |
| 351 rcall WaitMSSP | |
| 623 | 352 movff SSP1BUF,compass_DX+0 ; data byte |
| 353 bsf SSP1CON2,PEN ; stop condition | |
| 582 | 354 rcall WaitMSSP |
| 623 | 355 btfss flip_screen ; 180° rotation? |
| 356 return ; NO - done | |
| 357 banksel compass_DX ; YES - flip X | |
| 358 comf compass_DX+1 ; - 16 bit sign change | |
| 582 | 359 negf compass_DX+0 |
| 623 | 360 btfsc STATUS,C ; - carry to propagate? |
| 361 incf compass_DX+1,F ; YES - do it | |
| 582 | 362 banksel common |
| 363 return | |
| 364 | |
| 623 | 365 I2C_RX_compass1: ; new compass |
| 366 bsf SSP1CON2,SEN ; start condition | |
| 582 | 367 rcall WaitMSSP |
| 368 movlw 0x3C ; address | |
| 369 rcall I2C_TX | |
| 370 movlw b'10001000' ; 0x08 with auto-increment (MSB=1) | |
| 371 rcall I2C_TX | |
| 623 | 372 bsf SSP1CON2,RSEN ; repeated start condition (!) |
| 582 | 373 rcall WaitMSSP |
| 374 movlw 0x3D ; address | |
| 375 rcall I2C_TX | |
| 623 | 376 ;rcall WaitMSSP ; TODO needed? (mH) |
| 377 rcall I2C_OneByteRX ; get one byte | |
| 378 movff SSP1BUF,lo ; data byte | |
| 379 rcall I2C_OneByteRX ; get one byte | |
| 380 movff SSP1BUF,hi ; data byte | |
| 582 | 381 rcall I2C_TwoBytesRX_div8_2 |
| 623 | 382 MOVII mpr,compass_DX |
| 383 btfss flip_screen ; 180° rotation? | |
| 384 bra I2C_RX_compass1_1 ; NO | |
| 385 banksel compass_DX ; YES - flip X | |
| 386 comf compass_DX+1 ; - 16 bit sign change | |
| 582 | 387 negf compass_DX+0 |
| 623 | 388 btfsc STATUS,C ; - carry to propagate? |
| 389 incf compass_DX+1,F ; YES - do it | |
| 582 | 390 banksel common |
| 427 | 391 I2C_RX_compass1_1: |
| 623 | 392 rcall I2C_OneByteRX ; get one byte |
| 393 movff SSP1BUF,lo ; data byte | |
| 394 rcall I2C_OneByteRX ; get one byte | |
| 395 movff SSP1BUF,hi ; data byte | |
| 582 | 396 rcall I2C_TwoBytesRX_div8_2 |
| 623 | 397 MOVII mpr,compass_DY |
| 398 btfss flip_screen ; 180° rotation? | |
| 399 bra I2C_RX_compass1_2 ; NO | |
| 400 banksel compass_DY ; YES - flip Y | |
| 401 comf compass_DY+1 ; - 16 bit sign change | |
| 582 | 402 negf compass_DY+0 |
| 623 | 403 btfsc STATUS,C ; - carry to propagate? |
| 404 incf compass_DY+1,F ; YES - do it | |
| 405 banksel common | |
| 427 | 406 I2C_RX_compass1_2: |
| 623 | 407 rcall I2C_OneByteRX ; get one byte |
| 408 movff SSP1BUF,lo ; data byte | |
| 582 | 409 bsf SSP1CON2, RCEN ; Enable receive mode |
| 410 rcall WaitMSSP | |
| 623 | 411 movff SSP1BUF,hi ; data byte |
| 582 | 412 rcall I2C_TwoBytesRX_div8_2 |
| 623 | 413 MOVII mpr,compass_DZ |
| 414 bsf SSP1CON2,PEN ; stop condition | |
| 415 bra WaitMSSP ; ... and return | |
| 560 | 416 |
| 582 | 417 I2C_RX_compass2: ; newest compass |
| 623 | 418 bsf SSP1CON2,SEN ; start condition |
| 582 | 419 rcall WaitMSSP |
| 420 movlw 0x3C ; address | |
| 421 rcall I2C_TX | |
| 422 movlw 0xE8 ; 0x68 with auto-increment (MSB=1) | |
| 423 rcall I2C_TX | |
| 623 | 424 bsf SSP1CON2,RSEN ; repeated start condition (!) |
| 582 | 425 rcall WaitMSSP |
| 426 movlw 0x3D ; address | |
| 427 rcall I2C_TX | |
| 624 | 428 I2C_RX_compass2_xx: ; compass 3 enters here |
| 582 | 429 ; rcall WaitMSSP |
| 623 | 430 rcall I2C_OneByteRX ; get one byte |
| 431 movff SSP1BUF,lo ; data byte | |
| 432 rcall I2C_OneByteRX ; get one byte | |
| 433 movff SSP1BUF,hi ; data byte | |
| 582 | 434 ; rcall I2C_TwoBytesRX_div8_2 |
| 623 | 435 btfsc flip_screen ; 180° rotation? |
| 436 bra I2C_RX_compass2_1 ; YES - do nothing with X | |
| 437 ; NO - flip X | |
| 438 comf hi ; - 16 bit sign change | |
| 582 | 439 negf lo |
| 623 | 440 btfsc STATUS,C ; - carry to propagate? |
| 441 incf hi,F ; YES - do it | |
| 582 | 442 I2C_RX_compass2_1: |
| 623 | 443 MOVII mpr,compass_DX |
| 444 rcall I2C_OneByteRX ; get one byte | |
| 445 movff SSP1BUF,lo ; data byte | |
| 446 rcall I2C_OneByteRX ; get one byte | |
| 447 movff SSP1BUF,hi ; data byte | |
| 582 | 448 ; rcall I2C_TwoBytesRX_div8_2 |
| 623 | 449 btfss flip_screen ; 180° rotation? |
| 450 bra I2C_RX_compass2_2 ; NO - do nothing with Y | |
| 451 ; YES - flip Y | |
| 452 comf hi ; - 16 bit sign change | |
| 582 | 453 negf lo |
| 623 | 454 btfsc STATUS,C ; - carry to propagate? |
| 455 incf hi,F ; YES - do it | |
| 456 I2C_RX_compass2_2: | |
| 457 MOVII mpr,compass_DY | |
| 458 rcall I2C_OneByteRX ; get one byte | |
| 459 movff SSP1BUF,lo ; data byte | |
| 460 rcall I2C_OneByteRX ; get one byte | |
| 461 movff SSP1BUF,hi ; data byte | |
| 582 | 462 ; rcall I2C_TwoBytesRX_div8_2 |
| 623 | 463 MOVII mpr,compass_DZ |
| 464 bsf SSP1CON2,PEN ; stop condition | |
| 582 | 465 bra WaitMSSP ;(And return) |
| 466 | |
| 624 | 467 I2C_RX_compass3: |
| 468 bsf SSP1CON2,SEN ; Start condition | |
| 469 rcall WaitMSSP | |
| 470 movlw 0x3C ; address | |
| 471 rcall I2C_TX | |
| 472 movlw 0xA8 ; 0x28 with auto-increment (MSB=1) | |
| 473 rcall I2C_TX | |
| 474 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
| 475 rcall WaitMSSP | |
| 476 movlw 0x3D ; address | |
| 477 rcall I2C_TX | |
| 478 bra I2C_RX_compass2_xx | |
| 479 | |
| 623 | 480 ENDIF ; _compass |
| 481 | |
| 482 ;----------------------------------------------------------------------------- | |
| 582 | 483 |
| 484 global I2C_init_compass | |
| 0 | 485 I2C_init_compass: |
| 582 | 486 bsf compass_enabled |
| 487 bcf compass_type2 | |
| 624 | 488 bcf compass_type3 |
| 489 | |
| 490 ; probe compass 3 | |
| 491 bsf SSP1CON2,SEN ; Start condition | |
| 492 rcall WaitMSSP | |
| 493 movlw 0x3A ; Address byte + Write bit | |
| 494 movwf SSP1BUF ; control byte | |
| 495 rcall WaitMSSP | |
| 496 btfss SSP1CON2,ACKSTAT ; ACK? | |
| 497 bsf compass_type3 ; ACK send. compass2 present | |
| 498 bsf SSP1CON2,PEN ; Stop condition | |
| 499 rcall WaitMSSP | |
| 500 | |
| 501 btfsc compass_type3 | |
| 502 bra I2C_init_compass3 ; Compass3 | |
| 623 | 503 |
| 504 ; check for compass2 | |
| 505 bsf SSP1CON2,SEN ; start condition | |
| 582 | 506 rcall WaitMSSP |
| 623 | 507 movlw 0x32 ; address byte + Write bit |
| 582 | 508 movwf SSP1BUF ; control byte |
| 509 rcall WaitMSSP | |
| 510 btfss SSP1CON2,ACKSTAT ; ACK? | |
| 623 | 511 bsf compass_type2 ; YES - ACK send, compass2 present |
| 512 bsf SSP1CON2,PEN ; NO - stop condition | |
| 582 | 513 rcall WaitMSSP |
| 514 btfsc compass_type2 | |
| 623 | 515 bra I2C_init_compass2 ; compass2 |
| 516 | |
| 517 ; check for compass0 or compass1... | |
| 582 | 518 bsf compass_type ; set flag |
| 623 | 519 bsf SSP1CON2,SEN ; start condition |
| 582 | 520 rcall WaitMSSP |
| 521 movlw 0x3C ; address | |
| 522 rcall I2C_TX | |
| 523 movlw 0x0F | |
| 524 rcall I2C_TX | |
| 623 | 525 bsf SSP1CON2,PEN ; stop condition |
| 526 rcall WaitMSSP | |
| 582 | 527 bcf PIR1,SSP1IF |
| 623 | 528 bsf SSP1CON2,SEN ; start condition |
| 582 | 529 rcall WaitMSSP |
| 530 movlw 0x3D ; address | |
| 531 rcall I2C_TX | |
| 623 | 532 rcall I2C_OneByteRX ; get one byte |
| 582 | 533 movlw 0x49 ; 0x49 = Compass1 |
| 534 cpfseq SSP1BUF | |
| 535 bcf compass_type ; clear flag | |
| 623 | 536 bsf SSP1CON2,PEN ; stop condition |
| 582 | 537 rcall WaitMSSP |
| 623 | 538 btfsc compass_type ; compass1 ? |
| 539 bra I2C_init_compass1 ; YES | |
| 582 | 540 |
| 623 | 541 ; init compass0 |
| 542 bsf SSP1CON2,SEN ; start condition | |
| 582 | 543 rcall WaitMSSP |
| 544 movlw 0x3C ; address | |
| 545 rcall I2C_TX | |
| 546 movlw 0x00 | |
| 547 rcall I2C_TX | |
| 623 | 548 ; movlw b'01101001' ; ConfigA: 3 Hz, 8 samples averaged, test mode (positive bias) |
| 549 movlw b'01101000' ; ConfigA: 3 Hz, 8 samples averaged | |
| 582 | 550 rcall I2C_TX |
| 20 | 551 I2C_init_compass_common: |
| 623 | 552 movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) |
| 582 | 553 swapf i2c_temp1,F |
| 554 comf i2c_temp1,F | |
| 555 bcf STATUS,C | |
| 556 rlcf i2c_temp1 | |
| 557 movf i2c_temp1,W | |
| 558 clrf i2c_temp1 | |
| 559 rcall I2C_TX | |
| 623 | 560 movlw b'00000000' ; continuous mode |
| 582 | 561 rcall I2C_TX |
| 623 | 562 bsf SSP1CON2,PEN ; stop condition |
| 563 bra WaitMSSP ; ... and return | |
| 0 | 564 |
| 427 | 565 I2C_init_compass1: |
| 623 | 566 bsf SSP1CON2,SEN ; start condition |
| 582 | 567 rcall WaitMSSP |
| 568 movlw 0x3C ; address | |
| 569 rcall I2C_TX | |
| 570 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
| 571 rcall I2C_TX | |
| 572 movlw b'00000000' ; CTRL0 | |
| 573 rcall I2C_TX | |
| 623 | 574 movlw b'00101111' ; CTRL1 (6.25 Hz, BDU=0, x,y,z = ON) |
| 582 | 575 rcall I2C_TX |
| 623 | 576 movlw b'11000000' ; CTRL2 (50 Hz, +/- 2g) |
| 582 | 577 rcall I2C_TX |
| 578 movlw b'00000000' ; CTRL3 | |
| 579 rcall I2C_TX | |
| 580 movlw b'00000000' ; CTRL4 | |
| 581 rcall I2C_TX | |
| 623 | 582 movlw b'01100100' ; CTRL5 HIGH res, 6.25 Hz |
| 582 | 583 rcall I2C_TX |
| 429 | 584 init_compass1_common: |
| 623 | 585 movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) |
| 586 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) | |
| 582 | 587 dcfsnz i2c_temp1,F ; = 1? |
| 623 | 588 movlw b'01100000' ; YES - CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) |
| 582 | 589 dcfsnz i2c_temp1,F ; = 2? |
| 623 | 590 movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) |
| 582 | 591 dcfsnz i2c_temp1,F ; = 3? |
| 623 | 592 movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) |
| 582 | 593 dcfsnz i2c_temp1,F ; = 4? |
| 623 | 594 movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) |
| 582 | 595 dcfsnz i2c_temp1,F ; = 5? |
| 623 | 596 movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) |
| 582 | 597 dcfsnz i2c_temp1,F ; = 6? |
| 623 | 598 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) |
| 582 | 599 dcfsnz i2c_temp1,F ; = 7? |
| 623 | 600 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) |
| 582 | 601 rcall I2C_TX |
| 602 movlw b'00000000' ; CTRL7 Continuous Mode | |
| 603 rcall I2C_TX | |
| 623 | 604 bsf SSP1CON2,PEN ; stop condition |
| 605 bra WaitMSSP ; ... and return | |
| 582 | 606 |
| 560 | 607 I2C_init_compass2: |
| 623 | 608 bsf SSP1CON2,SEN ; start condition |
| 609 rcall WaitMSSP | |
| 610 movlw 0x3C ; address | |
| 611 rcall I2C_TX | |
| 612 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) | |
| 613 rcall I2C_TX | |
| 614 movlw b'00000000' ; CFG_REG_A_M 0x60 (10 Hz, continuous) | |
| 615 rcall I2C_TX | |
| 616 movlw b'00000000' ; CFG_REG_B_M 0x61 (low-pass filter off, set pulse is released every 63 ODR) | |
| 617 rcall I2C_TX | |
| 618 movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62 | |
| 619 rcall I2C_TX | |
| 620 bsf SSP1CON2,PEN ; stop condition | |
| 621 bra WaitMSSP ; ... and return | |
| 582 | 622 |
| 624 | 623 I2C_init_compass3: |
| 624 bsf SSP1CON2,SEN ; Start condition | |
| 625 rcall WaitMSSP | |
| 626 movlw 0x3C ; address | |
| 627 rcall I2C_TX | |
| 628 movlw 0xA0 ; 0x20 with auto-increment (MSB=1) | |
| 629 rcall I2C_TX | |
| 630 movlw b'00010000' ; CTRL_REG1_M (10Hz) 0x20 | |
| 631 rcall I2C_TX | |
| 632 movlw b'01100000' ; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21 | |
| 633 rcall I2C_TX | |
| 634 movlw b'01000000' ; CTRL_REG3_M (Continuous) 0x22 | |
| 635 rcall I2C_TX | |
| 636 movlw b'00000000' ; CTRL_REG4_M (Z in Low-power mode) 0x23 | |
| 637 rcall I2C_TX | |
| 638 movlw b'00000000' ; CTRL_REG5_M 0x24 | |
| 639 rcall I2C_TX | |
| 640 movlw b'00000000' ; CTRL_REG5_M 0x24 | |
| 641 rcall I2C_TX | |
| 642 bsf SSP1CON2,PEN ; Stop condition | |
| 643 bra WaitMSSP ;(And return) | |
| 644 | |
| 582 | 645 |
| 646 global I2C_sleep_compass | |
| 0 | 647 I2C_sleep_compass: |
| 623 | 648 bcf compass_enabled |
| 624 | 649 btfsc compass_type3 ; compass3? |
| 650 bra I2C_sleep_compass3 ; YES | |
| 623 | 651 btfsc compass_type2 ; compass2 ? |
| 652 bra I2C_sleep_compass2 ; YES | |
| 653 btfsc compass_type ; compass1 ? | |
| 654 bra I2C_sleep_compass1 ; YES | |
| 560 | 655 I2C_sleep_compass0: |
| 623 | 656 bsf SSP1CON2,SEN ; start condition |
| 582 | 657 rcall WaitMSSP |
| 658 movlw 0x3C ; address | |
| 659 rcall I2C_TX | |
| 660 movlw 0x00 | |
| 661 rcall I2C_TX | |
| 662 movlw b'01101000' ; ConfigA | |
| 663 rcall I2C_TX | |
| 664 movlw b'00100000' ; ConfigB | |
| 665 rcall I2C_TX | |
| 623 | 666 movlw b'00000010' ; idle mode |
| 582 | 667 rcall I2C_TX |
| 623 | 668 bsf SSP1CON2,PEN ; stop condition |
| 669 bra WaitMSSP ; ... and return | |
| 0 | 670 |
| 427 | 671 I2C_sleep_compass1: |
| 623 | 672 bsf SSP1CON2,SEN ; start condition |
| 582 | 673 rcall WaitMSSP |
| 674 movlw 0x3C ; address | |
| 675 rcall I2C_TX | |
| 676 movlw 0x20 ; CTRL_REG1 | |
| 677 rcall I2C_TX | |
| 623 | 678 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor power-down mode |
| 582 | 679 rcall I2C_TX |
| 623 | 680 bsf SSP1CON2,PEN ; stop condition |
| 582 | 681 rcall WaitMSSP |
| 623 | 682 bsf SSP1CON2,SEN ; start condition |
| 582 | 683 rcall WaitMSSP |
| 684 movlw 0x3C ; address | |
| 685 rcall I2C_TX | |
| 686 movlw 0x26 ; CTRL_REG7 | |
| 687 rcall I2C_TX | |
| 623 | 688 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode |
| 582 | 689 rcall I2C_TX |
| 623 | 690 bsf SSP1CON2,PEN ; stop condition |
| 691 bra WaitMSSP ; and return | |
| 560 | 692 |
| 693 I2C_sleep_compass2: | |
| 623 | 694 ; magnetic |
| 695 bsf SSP1CON2,SEN ; start condition | |
| 696 rcall WaitMSSP | |
| 697 movlw 0x3C ; address | |
| 698 rcall I2C_TX | |
| 699 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) | |
| 700 rcall I2C_TX | |
| 701 movlw b'00000011' ; CFG_REG_A_M 0x60 (idle mode)) | |
| 702 rcall I2C_TX | |
| 703 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) | |
| 704 rcall I2C_TX | |
| 705 movlw b'01010001' ; CFG_REG_C_M 0x62 | |
| 706 rcall I2C_TX | |
| 707 movlw b'00000000' ; INT_CTRL_REG_M 0x63 | |
| 708 rcall I2C_TX | |
| 709 bsf SSP1CON2,PEN ; stop condition | |
| 710 bra WaitMSSP ; ... and return | |
| 582 | 711 |
| 624 | 712 I2C_sleep_compass3: |
| 713 ; magnetic | |
| 714 bsf SSP1CON2,SEN ; Start condition | |
| 715 rcall WaitMSSP | |
| 716 movlw 0x3C ; address | |
| 717 rcall I2C_TX | |
| 718 movlw 0xA2 ; 0x22 with auto-increment (MSB=1) | |
| 719 movlw b'01000010' ; CTRL_REG3_M (Power-down) 0x22 | |
| 720 rcall I2C_TX | |
| 721 bsf SSP1CON2,PEN ; Stop condition | |
| 722 bra WaitMSSP ;(And return) | |
| 723 | |
| 560 | 724 I2C_sleep_accelerometer2: |
| 623 | 725 ; accelerometer |
| 726 bsf SSP1CON2,SEN ; start condition | |
| 727 rcall WaitMSSP | |
| 728 movlw 0x32 ; address | |
| 729 rcall I2C_TX | |
| 730 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
| 731 rcall I2C_TX | |
| 732 movlw b'00000000' ; TEMP_CFG_REG_A 0x1F (temp sensor off) | |
| 733 rcall I2C_TX | |
| 734 movlw b'00000000' ; CTRL_REG1_A 0x20 (all off) | |
| 735 rcall I2C_TX | |
| 736 bsf SSP1CON2,PEN ; stop condition | |
| 737 bra WaitMSSP ; ... and return | |
| 738 | |
| 624 | 739 I2C_sleep_accelerometer3: |
| 740 ; accelerometer | |
| 741 bsf SSP1CON2,SEN ; Start condition | |
| 742 rcall WaitMSSP | |
| 743 movlw 0x3A ; address | |
| 744 rcall I2C_TX | |
| 745 movlw 0x20 | |
| 746 rcall I2C_TX | |
| 747 movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = ON) 0x20 | |
| 748 rcall I2C_TX | |
| 749 bsf SSP1CON2,PEN ; Stop condition | |
| 750 bra WaitMSSP ; (And return) | |
| 751 | |
| 0 | 752 |
| 615 | 753 WaitMSSP: |
| 754 decfsz i2c_temp1,F ; check for timeout during I2C action | |
| 755 bra WaitMSSP2 | |
| 756 bra I2CFail ; timeout occurred | |
| 757 WaitMSSP2: | |
| 758 btfss PIR1,SSP1IF | |
| 759 bra WaitMSSP | |
| 760 clrf i2c_temp1 | |
| 761 bcf PIR1,SSP1IF | |
| 762 return | |
| 763 | |
| 764 I2C_WaitforACK: | |
| 765 btfss SSP1CON2,ACKSTAT ; checks for ACK bit from slave | |
| 766 return | |
| 767 I2CFail: | |
| 768 rcall I2CReset ; I2C Reset | |
| 769 bcf PIR1,SSP1IF | |
| 770 clrf i2c_temp1 | |
| 771 bsf i2c_error_flag ; set error flag | |
| 772 return | |
| 773 | |
| 774 I2CReset: ; something went wrong (slave holds SDA low?) | |
| 775 clrf SSP1CON1 ; wake-up slave and reset entire module | |
| 776 clrf SSP1CON2 | |
| 777 clrf SSP1STAT | |
| 778 bcf TRISC,3 ; SCL OUTPUT | |
| 779 bsf TRISC,4 ; SDA input | |
| 780 bcf PORTC,3 | |
| 781 movlw d'9' | |
| 782 movwf i2c_temp1 ; clock-out 9 clock cycles manually | |
| 783 I2CReset_1: | |
| 784 bsf PORTC,3 ; SCL = 1 | |
| 785 nop | |
| 786 nop | |
| 787 nop | |
| 788 nop | |
| 789 btfsc PORTC,4 ; SDA = 1 ? | |
| 790 bra I2CReset_2 ; YES - =1, SDA has been released from slave | |
| 791 bcf PORTC,3 ; NO - set SCL = 0 | |
| 792 nop | |
| 793 nop | |
| 794 bcf PORTC,3 | |
| 795 nop | |
| 796 nop | |
| 797 decfsz i2c_temp1,F | |
| 798 bra I2CReset_1 ; check for nine clock cycles | |
| 799 I2CReset_2: | |
| 800 bsf TRISC,3 ; SCL Input | |
| 801 clrf SSP1CON1 ; setup I²C mode | |
| 802 WAITMS d'10' ; reset-timeout for I2C devices | |
| 803 movlw b'00000000' ; with slew rate control | |
| 804 movwf SSP1STAT | |
| 805 movlw b'00101000' | |
| 806 movwf SSP1CON1 | |
| 807 movlw b'00000000' | |
| 808 movwf SSP1CON2 | |
| 809 movlw 0x27 | |
| 810 movwf SSP1ADD | |
| 811 return | |
| 623 | 812 |
| 813 | |
| 582 | 814 global I2C_init_accelerometer |
| 0 | 815 I2C_init_accelerometer: |
| 624 | 816 btfsc compass_type3 ; compass3? |
| 817 bra I2C_init_accelerometer3 ; YES | |
| 818 | |
| 623 | 819 btfsc compass_type2 ; compass2 ? |
| 820 bra I2C_init_accelerometer2 ; YES | |
| 560 | 821 |
| 623 | 822 btfsc compass_type ; compass1 ? |
| 823 return ; YES - ignore | |
| 427 | 824 |
| 623 | 825 rcall I2C_sleep_accelerometer ; registers can only be changed in standby mode |
| 0 | 826 |
| 623 | 827 bsf SSP1CON2,SEN ; start condition |
| 582 | 828 rcall WaitMSSP |
| 829 movlw 0x38 ; address | |
| 830 rcall I2C_TX | |
| 831 movlw 0x0E ; XYZ_DATA_CFG | |
| 832 rcall I2C_TX | |
| 623 | 833 movlw b'00000000' ; high pass filter = 0, +/- 2g range |
| 582 | 834 rcall I2C_TX |
| 623 | 835 bsf SSP1CON2,PEN ; stop condition |
| 582 | 836 rcall WaitMSSP |
| 0 | 837 |
| 623 | 838 bsf SSP1CON2,SEN ; start condition |
| 582 | 839 rcall WaitMSSP |
| 840 movlw 0x38 ; address | |
| 841 rcall I2C_TX | |
| 842 movlw 0x2A ; CTRL_REG1 | |
| 843 rcall I2C_TX | |
| 623 | 844 ; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode |
| 845 movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode | |
| 582 | 846 rcall I2C_TX |
| 623 | 847 movlw b'00000010' ; CTRL_REG2: high-res in active mode |
| 582 | 848 rcall I2C_TX |
| 623 | 849 bsf SSP1CON2,PEN ; stop condition |
| 582 | 850 rcall WaitMSSP |
| 0 | 851 |
| 623 | 852 bsf SSP1CON2,SEN ; start condition |
| 582 | 853 rcall WaitMSSP |
| 854 movlw 0x38 ; address | |
| 855 rcall I2C_TX | |
| 856 movlw 0x2A ; CTRL_REG1 | |
| 857 rcall I2C_TX | |
| 623 | 858 ; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode |
| 859 movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode | |
| 582 | 860 rcall I2C_TX |
| 623 | 861 bsf SSP1CON2,PEN ; stop condition |
| 862 bra WaitMSSP ; ... and return | |
| 582 | 863 |
| 560 | 864 I2C_init_accelerometer2: |
| 623 | 865 bsf SSP1CON2,SEN ; start condition |
| 582 | 866 rcall WaitMSSP |
| 867 movlw 0x32 ; address | |
| 868 rcall I2C_TX | |
| 869 movlw 0x9F ; 1F with auto-increment (MSB=1) | |
| 870 rcall I2C_TX | |
| 871 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) | |
| 872 rcall I2C_TX | |
| 873 movlw b'01010111' ; CTRL_REG1_A (100Hz, x,y,z = ON) | |
| 874 rcall I2C_TX | |
| 875 movlw b'00000000' ; CTRL_REG2_A | |
| 876 rcall I2C_TX | |
| 877 ; movlw b'00000000' ; CTRL_REG3_A | |
| 878 ; rcall I2C_TX | |
| 879 ; movlw b'00000000' ; CTRL_REG4_A (BDU=0, +/-2g, | |
| 880 ; rcall I2C_TX | |
| 881 ; movlw b'00000000' ; CTRL_REG5_A | |
| 882 ; rcall I2C_TX | |
| 623 | 883 bsf SSP1CON2,PEN ; stop condition |
| 884 bra WaitMSSP ; ... and return | |
| 885 | |
| 624 | 886 I2C_init_accelerometer3: |
| 887 bsf SSP1CON2,SEN ; Start condition | |
| 888 rcall WaitMSSP | |
| 889 movlw 0x3A ; address | |
| 890 rcall I2C_TX | |
| 891 movlw 0x20 | |
| 892 rcall I2C_TX | |
| 893 movlw b'00110111' ; CTRL_REG1_A (100Hz, x,y,z = ON) 0x20 | |
| 894 rcall I2C_TX | |
| 895 movlw b'00000000' ; CTRL_REG2_A 0x21 | |
| 896 rcall I2C_TX | |
| 897 movlw b'00000000' ; CTRL_REG3_A 0x22 | |
| 898 rcall I2C_TX | |
| 899 bsf SSP1CON2,PEN ; Stop condition | |
| 900 bra WaitMSSP ; (And return) | |
| 901 | |
| 0 | 902 |
| 582 | 903 global I2C_sleep_accelerometer |
| 0 | 904 I2C_sleep_accelerometer: |
| 624 | 905 btfsc compass_type3 ; Compass3 |
| 906 bra I2C_sleep_accelerometer3 ; YES | |
| 582 | 907 btfsc compass_type2 ; Compass2 |
| 623 | 908 bra I2C_sleep_accelerometer2 ; YES |
| 582 | 909 btfsc compass_type ; compass1? |
| 623 | 910 return ; YES - ignore |
| 427 | 911 |
| 623 | 912 bsf SSP1CON2,SEN ; start condition |
| 582 | 913 rcall WaitMSSP |
| 914 movlw 0x38 ; address | |
| 915 rcall I2C_TX | |
| 916 movlw 0x2A ; CTRL_REG1 | |
| 917 rcall I2C_TX | |
| 623 | 918 movlw b'00000000' ; standby mode |
| 582 | 919 rcall I2C_TX |
| 623 | 920 bsf SSP1CON2,PEN ; stop condition |
| 921 bra WaitMSSP ; ... and return | |
| 582 | 922 |
|
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
923 lt2942_init_again: |
| 582 | 924 clrf i2c_temp1 |
| 623 | 925 movlw 0x02 ; point to accumulated charge registers |
|
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
926 rcall I2C_TX_GAUGE |
| 623 | 927 movff battery_accumulated_charge+1,SSP1BUF ; data byte |
|
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
928 rcall WaitMSSP |
|
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
929 rcall I2C_WaitforACK |
| 623 | 930 movff battery_accumulated_charge+0,SSP1BUF ; data byte |
|
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
931 rcall WaitMSSP |
|
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
932 rcall I2C_WaitforACK |
| 623 | 933 bsf SSP1CON2,PEN ; stop condition |
| 560 | 934 rcall WaitMSSP |
| 623 | 935 MOVII battery_accumulated_charge,sub_a |
|
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
936 ; and init again... |
| 560 | 937 |
| 582 | 938 global lt2942_init |
| 623 | 939 lt2942_init: ; setup control register B |
| 582 | 940 clrf i2c_temp1 |
| 623 | 941 movlw 0x01 ; point to control reg B |
| 467 | 942 rcall I2C_TX_GAUGE |
| 623 | 943 movlw b'11111000' ; automatic conversion every two seconds |
| 944 movff WREG, SSP1BUF ; data byte | |
| 113 | 945 rcall WaitMSSP |
| 946 rcall I2C_WaitforACK | |
| 623 | 947 bsf SSP1CON2,PEN ; stop condition |
| 948 bra WaitMSSP ; ... and return | |
| 113 | 949 |
| 950 global lt2942_get_status | |
| 623 | 951 lt2942_get_status: ; read status register |
| 952 bcf battery_gauge_available ; clear flag | |
| 582 | 953 clrf i2c_temp1 |
| 623 | 954 movlw 0x00 ; point to status register |
| 467 | 955 rcall I2C_TX_GAUGE |
| 956 rcall I2C_RX_GAUGE | |
| 113 | 957 movff SSP1BUF,WREG |
| 582 | 958 btfss WREG,7 ; 2942 found? |
| 623 | 959 bsf battery_gauge_available ; YES - set flag |
| 960 bsf SSP1CON2,PEN ; stop condition | |
| 961 bra WaitMSSP ; ... and return | |
| 113 | 962 |
| 963 | |
| 964 global lt2942_get_voltage | |
| 623 | 965 lt2942_get_voltage: ; read battery voltage registers |
| 582 | 966 clrf i2c_temp1 |
| 623 | 967 movlw 0x08 ; point to voltage registers |
| 448 | 968 rcall I2C_TX_GAUGE |
| 969 rcall I2C_RX_GAUGE | |
| 623 | 970 bsf SSP1CON2,ACKEN ; master acknowledge |
| 615 | 971 rcall WaitMSSP |
| 972 movff SSP1BUF,xA+1 | |
| 623 | 973 bsf SSP1CON2, RCEN ; enable receive mode |
| 615 | 974 rcall WaitMSSP |
| 975 movff SSP1BUF,xA+0 | |
| 623 | 976 bsf SSP1CON2,PEN ; stop condition |
| 615 | 977 rcall WaitMSSP |
| 978 | |
| 623 | 979 ; convert voltage from raw value to Volt |
| 980 MOVLI .6000,xB ; load conversion multiplicand into xB | |
| 981 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
| 982 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
| 983 movff xC+2,batt_voltage+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result | |
| 984 movff xC+3,batt_voltage+1 ; ... | |
| 615 | 985 |
| 623 | 986 tstfsz batt_voltage+1 ; < 256 mV ? |
| 987 return ; NO - done | |
| 988 bra lt2942_init ; YES - ... and return | |
| 989 | |
| 615 | 990 |
| 623 | 991 global lt2942_get_temperature |
| 992 lt2942_get_temperature: ; read battery temperature | |
| 993 clrf i2c_temp1 | |
| 994 movlw 0x0C ; point to temperature register | |
| 995 call I2C_TX_GAUGE | |
| 996 call I2C_RX_GAUGE | |
| 997 bsf SSP1CON2,ACKEN ; master acknowledge | |
| 998 rcall WaitMSSP | |
| 999 movff SSP1BUF,xA+1 ; store raw temperature, high byte | |
| 1000 bsf SSP1CON2, RCEN ; enable receive mode | |
| 1001 rcall WaitMSSP | |
| 1002 movff SSP1BUF,xA+0 ; store raw temperature, low byte | |
| 1003 bsf SSP1CON2,PEN ; stop condition | |
| 1004 rcall WaitMSSP | |
| 1005 | |
| 1006 ; convert temperature from raw value to Kelvin | |
| 1007 MOVLI .6000,xB ; load conversion multiplicand into xB | |
| 1008 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
| 1009 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
| 1010 movff xC+2,battery_temperature+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result | |
| 1011 movff xC+3,battery_temperature+1 ; ... | |
| 1012 | |
| 1013 ; check if battery is charged right now | |
| 1014 btfss cc_active ; in CC charging mode? | |
| 1015 return ; NO - not charging, done | |
| 1016 | |
| 1017 ; check for over-temperature while charging | |
| 1018 MOVLI max_battery_charge_temp,sub_a | |
| 1019 MOVII battery_temperature, sub_b | |
| 1020 call cmpU16 ; sub_a - sub_b (with UNSIGNED values) | |
| 1021 btfss neg_flag ; result negative? | |
| 1022 return ; NO - temperature <= threshold, ok, done | |
| 1023 ; YES - too hot, disable charging circuitry | |
| 1024 bsf charge_disable ; - set charging-inhibit signal | |
| 1025 bcf charge_enable ; - activate charging-inhibit signal | |
| 1026 bsf battery_overtemp ; - flag that the battery charging over-temperature protection has tripped | |
| 1027 return | |
| 1028 | |
| 113 | 1029 |
| 1030 global lt2942_get_accumulated_charge | |
| 623 | 1031 lt2942_get_accumulated_charge: ; read accumulated charge and compute percent |
| 582 | 1032 clrf i2c_temp1 |
| 623 | 1033 movlw 0x00 ; point to status register |
| 467 | 1034 rcall I2C_TX_GAUGE |
| 1035 rcall I2C_RX_GAUGE | |
| 623 | 1036 bsf SSP1CON2,ACKEN ; master acknowledge |
| 113 | 1037 rcall WaitMSSP |
| 466 | 1038 movff SSP1BUF,gauge_status_byte |
| 1039 | |
| 623 | 1040 bsf SSP1CON2, RCEN ; enable receive mode |
| 1041 rcall WaitMSSP ; dummy read (control byte) | |
| 467 | 1042 movf SSP1BUF,W |
| 623 | 1043 bsf SSP1CON2,ACKEN ; master acknowledge |
| 467 | 1044 rcall WaitMSSP |
| 582 | 1045 |
| 623 | 1046 bsf SSP1CON2, RCEN ; enable receive mode |
| 466 | 1047 rcall WaitMSSP |
| 623 | 1048 movff SSP1BUF,sub_a+1 |
| 1049 bsf SSP1CON2,ACKEN ; master acknowledge | |
| 113 | 1050 rcall WaitMSSP |
| 582 | 1051 |
| 623 | 1052 bsf SSP1CON2, RCEN ; enable receive mode |
| 1053 rcall WaitMSSP | |
| 1054 movff SSP1BUF,sub_a+0 | |
| 1055 bsf SSP1CON2,PEN ; stop condition | |
| 1056 rcall WaitMSSP | |
| 113 | 1057 |
| 623 | 1058 btfsc gauge_status_byte,0 ; UVLO event ? |
| 1059 rcall lt2942_init_again ; YES | |
| 1060 | |
| 1061 MOVII sub_a,battery_accumulated_charge ; save raw value | |
| 582 | 1062 |
| 1063 ; Compute batt_percent | |
| 1064 ; (charge-battery_offset)/365 | |
| 623 | 1065 MOVII battery_offset,sub_b |
| 582 | 1066 call subU16 ; sub_c = sub_a - sub_b (with signed values) |
| 623 | 1067 clrf batt_percent ; set to zero |
| 582 | 1068 btfsc neg_flag ; result negative? |
| 623 | 1069 bra lt2942_set_to_zero_percent ; YES - keep LT2942 at zero percent and return |
| 113 | 1070 |
| 623 | 1071 ; > zero, set batt_percent properly |
| 1072 MOVII sub_c,xA | |
| 1073 MOVII battery_capacity,xB | |
| 604 | 1074 call div16x16 ; xC = xA / xB with xA as remainder |
| 582 | 1075 movff xC+0,batt_percent |
| 1076 return | |
| 113 | 1077 |
| 449 | 1078 lt2942_set_to_zero_percent: |
| 582 | 1079 clrf i2c_temp1 |
| 623 | 1080 movlw 0x02 ; point to accumulated charge registers |
| 449 | 1081 rcall I2C_TX_GAUGE |
| 1082 movff battery_offset+1,SSP1BUF | |
| 1083 rcall WaitMSSP | |
| 1084 rcall I2C_WaitforACK | |
| 1085 movff battery_offset+0,SSP1BUF | |
| 1086 rcall WaitMSSP | |
| 1087 rcall I2C_WaitforACK | |
| 623 | 1088 bsf SSP1CON2,PEN ; stop condition |
| 1089 bra WaitMSSP ; ... and return | |
| 449 | 1090 |
| 113 | 1091 global lt2942_charge_done |
| 623 | 1092 lt2942_charge_done: ; reset accumulating registers to 0xFFFF |
| 582 | 1093 clrf i2c_temp1 |
| 623 | 1094 movlw 0x02 ; point to accumulated charge registers |
| 448 | 1095 rcall I2C_TX_GAUGE |
| 623 | 1096 setf SSP1BUF ; data byte |
| 113 | 1097 rcall WaitMSSP |
| 1098 rcall I2C_WaitforACK | |
| 623 | 1099 setf SSP1BUF ; data byte |
| 113 | 1100 rcall WaitMSSP |
| 1101 rcall I2C_WaitforACK | |
| 623 | 1102 bsf SSP1CON2,PEN ; stop condition |
| 1103 bra WaitMSSP ; ... and return | |
| 113 | 1104 |
| 623 | 1105 I2C_TX_GAUGE: ; send a byte to the LT2942 gauge IC |
| 1106 movwf i2c_temp2 ; data byte | |
| 1107 bsf SSP1CON2,SEN ; start condition | |
| 113 | 1108 rcall WaitMSSP |
| 623 | 1109 movlw b'11001000' ; address byte + Write bit |
| 582 | 1110 movwf SSP1BUF ; control byte |
| 113 | 1111 rcall WaitMSSP |
| 1112 rcall I2C_WaitforACK | |
| 582 | 1113 movf i2c_temp2,W |
| 623 | 1114 bra I2C_TX ; ... and return |
| 582 | 1115 |
| 113 | 1116 I2C_RX_GAUGE: |
| 623 | 1117 bsf SSP1CON2,SEN ; start condition |
| 113 | 1118 rcall WaitMSSP |
| 623 | 1119 movlw b'11001001' ; address byte + Read bit |
| 582 | 1120 movwf SSP1BUF ; control byte |
| 113 | 1121 rcall WaitMSSP |
| 1122 rcall I2C_WaitforACK | |
| 623 | 1123 bsf SSP1CON2, RCEN ; enable receive mode |
| 1124 bra WaitMSSP ; ... and return | |
| 582 | 1125 |
| 1126 | |
| 623 | 1127 ;============================================================================= |
| 604 | 1128 ; Transmitter Functions |
| 623 | 1129 ; |
| 604 | 1130 IFDEF _rx_functions |
| 1131 | |
| 560 | 1132 global I2C_probe_OSTC_rx |
| 1133 I2C_probe_OSTC_rx: | |
| 623 | 1134 bcf ostc_rx_present ; no TR module by default |
| 1135 clrf WREG ; bank-safe set to zero of ... | |
| 1136 movff WREG,rx_firmware_cur_major ; ... current TR module firmware, major | |
| 1137 movff WREG,rx_firmware_cur_minor ; ... current TR module firmware, minor | |
| 1138 movlw .5 ; max number of tries for detecting a TR module | |
| 1139 movwf hy ; initialize counter for tries | |
| 604 | 1140 I2C_probe_OSTC_rx_1: |
| 623 | 1141 bsf SSP1CON2,SEN ; start condition |
| 560 | 1142 rcall WaitMSSP |
| 623 | 1143 movlw 0x50 ; address byte + write bit |
| 582 | 1144 movwf SSP1BUF ; control byte |
| 560 | 1145 rcall WaitMSSP |
| 623 | 1146 btfss SSP1CON2,ACKSTAT ; ACK received? |
| 1147 bsf ostc_rx_present ; YES - TR module detected | |
| 1148 bsf SSP1CON2,PEN ; stop condition | |
| 560 | 1149 rcall WaitMSSP |
| 623 | 1150 btfss ostc_rx_present ; was a TR module detected? |
| 1151 return ; NO - done | |
| 560 | 1152 WAITMS .1 |
| 623 | 1153 bsf SSP1CON2,SEN ; start condition |
| 560 | 1154 rcall WaitMSSP |
| 623 | 1155 movlw 0x50 ; address byte + write bit |
| 582 | 1156 movwf SSP1BUF ; control byte |
| 560 | 1157 rcall WaitMSSP |
| 1158 rcall I2C_WaitforACK | |
| 1159 movlw 0x1B | |
| 623 | 1160 movwf SSP1BUF ; data byte (get firmware) |
| 560 | 1161 rcall WaitMSSP |
| 1162 rcall I2C_WaitforACK | |
| 623 | 1163 bsf SSP1CON2,PEN ; stop condition |
| 560 | 1164 rcall WaitMSSP |
| 1165 WAITMS .1 | |
| 623 | 1166 bsf SSP1CON2,SEN ; start condition |
| 560 | 1167 rcall WaitMSSP |
| 623 | 1168 movlw 0x51 ; address byte + Read bit |
| 582 | 1169 movwf SSP1BUF ; control byte |
| 560 | 1170 rcall WaitMSSP |
| 623 | 1171 bsf SSP1CON2,RCEN ; enable receive mode |
| 560 | 1172 rcall WaitMSSP |
| 623 | 1173 movff SSP1BUF,rx_firmware_cur_major ; store as firmware version, major |
| 1174 bsf SSP1CON2,ACKEN ; master acknowledge | |
| 560 | 1175 rcall WaitMSSP |
| 582 | 1176 |
| 560 | 1177 ; last byte in read from RX circuity always with a NACK! |
| 623 | 1178 bsf SSP1CON2,RCEN ; enable receive mode |
| 560 | 1179 rcall WaitMSSP |
| 623 | 1180 movff SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor |
| 582 | 1181 bsf SSP1CON2,ACKDT |
| 623 | 1182 bsf SSP1CON2,ACKEN ; master NOT acknowledge |
| 560 | 1183 rcall WaitMSSP |
| 623 | 1184 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
| 1185 bsf SSP1CON2,PEN ; stop condition | |
| 604 | 1186 rcall WaitMSSP |
| 1187 | |
| 623 | 1188 ; wait for TR module becoming ready |
| 1189 movff rx_firmware_cur_minor,i2c_temp1 ; copy firmware version to bank common, minor | |
| 1190 movlw .147 ; code for not ready, minor | |
| 1191 cpfseq i2c_temp1 ; equal? | |
| 1192 bra I2C_probe_OSTC_rx_2 ; NO - TR module ready | |
| 1193 movff rx_firmware_cur_major,i2c_temp1 ; YES - copy firmware version to bank common, major | |
| 1194 movlw .27 ; - code for not ready, major | |
| 1195 cpfseq i2c_temp1 ; - equal? | |
| 1196 bra I2C_probe_OSTC_rx_2 ; NO - TR module ready | |
| 1197 bsf active_reset_ostc_rx ; YES - apply reset to TR module | |
| 1198 WAITMS .5 ; - wait 5 ms | |
| 1199 bcf active_reset_ostc_rx ; - release reset | |
| 1200 WAITMS .250 ; - wait for 250 ms | |
| 1201 WAITMS .250 ; - wait another 250 ms | |
| 1202 clrf i2c_temp1 ; - clean-up i2c_temp1 | |
| 1203 decfsz hy,F ; - decrement counter for number of tries, became zero? | |
| 1204 bra I2C_probe_OSTC_rx_1 ; - NO - try again | |
| 1205 bcf ostc_rx_present ; - YES - something is wrong, flag TR module as not available | |
| 604 | 1206 I2C_probe_OSTC_rx_2: |
| 623 | 1207 clrf i2c_temp1 ; clean-up i2c_temp1 |
| 1208 return ; done | |
| 582 | 1209 |
| 560 | 1210 |
| 1211 global I2C_get_tankdata | |
| 1212 I2C_get_tankdata: | |
| 623 | 1213 bsf SSP1CON2,SEN ; start condition |
| 560 | 1214 rcall WaitMSSP |
| 623 | 1215 movlw 0x50 ; address byte + write bit |
| 582 | 1216 movwf SSP1BUF ; control byte |
| 560 | 1217 rcall WaitMSSP |
| 1218 rcall I2C_WaitforACK | |
| 623 | 1219 movlw 0x1E ; read buffer2 (48 bytes) |
| 1220 movwf SSP1BUF ; data byte | |
| 560 | 1221 rcall WaitMSSP |
| 1222 rcall I2C_WaitforACK | |
| 623 | 1223 bsf SSP1CON2,PEN ; stop condition |
| 560 | 1224 rcall WaitMSSP |
| 1225 WAITMS .1 | |
| 1226 ; read 48 bytes | |
| 623 | 1227 bsf SSP1CON2,SEN ; start condition |
| 560 | 1228 rcall WaitMSSP |
| 623 | 1229 movlw 0x51 ; address byte + read bit |
| 582 | 1230 movwf SSP1BUF ; control byte |
| 560 | 1231 rcall WaitMSSP |
| 1232 rcall I2C_WaitforACK | |
| 582 | 1233 movlw .47 ; 47 with ACK + 1 w/o ACK |
| 1234 movwf i2c_temp2 | |
| 623 | 1235 lfsr FSR2,rx_buffer |
| 560 | 1236 I2C_get_tankdata_loop_read: |
| 623 | 1237 bsf SSP1CON2, RCEN ; enable receive mode |
| 560 | 1238 rcall WaitMSSP |
| 1239 movff SSP1BUF,POSTINC2 | |
| 582 | 1240 bcf SSP1CON2,ACKDT |
| 623 | 1241 bsf SSP1CON2,ACKEN ; master acknowledge |
| 560 | 1242 rcall WaitMSSP |
| 582 | 1243 decfsz i2c_temp2,F |
| 1244 bra I2C_get_tankdata_loop_read | |
| 560 | 1245 ; 1 w/o ACK |
| 623 | 1246 bsf SSP1CON2, RCEN ; enable receive mode |
| 560 | 1247 rcall WaitMSSP |
| 1248 movff SSP1BUF,POSTINC2 | |
| 582 | 1249 bsf SSP1CON2,ACKDT |
| 623 | 1250 bsf SSP1CON2,ACKEN ; master NOT acknowledge |
| 560 | 1251 rcall WaitMSSP |
| 623 | 1252 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
| 1253 bsf SSP1CON2,PEN ; stop condition | |
| 1254 bra WaitMSSP ; ... and return | |
| 582 | 1255 |
| 1256 | |
| 560 | 1257 global I2C_update_OSTC_rx |
| 623 | 1258 I2C_update_OSTC_rx: ; transfer 64 byte to RX co-processor |
| 1259 ; setup for write | |
| 582 | 1260 bcf i2c_error_flag ; clear error flag |
| 623 | 1261 lfsr FSR2,buffer ; initialize pointer to send buffer used for verify |
| 1262 movlw .64 ; initialize loop counter: 64 byte with ACK | |
| 1263 movwf i2c_temp2 ; ... | |
| 1264 ; address write | |
| 1265 bsf SSP1CON2,SEN ; start condition | |
| 560 | 1266 rcall WaitMSSP |
| 623 | 1267 movlw 0x50 ; address byte + write bit |
| 582 | 1268 movwf SSP1BUF ; control byte |
| 560 | 1269 rcall WaitMSSP |
| 1270 rcall I2C_WaitforACK | |
| 623 | 1271 ; write 64 bytes |
| 1272 I2C_update_OSTC_loop: | |
| 1273 TBLRD*+ ; read a byte from program memory | |
| 1274 movff TABLAT,POSTINC2 ; copy to send buffer | |
| 1275 movff TABLAT,SSP1BUF ; copy to I2C data buffer | |
| 560 | 1276 rcall WaitMSSP |
| 1277 rcall I2C_WaitforACK | |
| 623 | 1278 decfsz i2c_temp2,F ;decrement loop counter, became zero? |
| 1279 bra I2C_update_OSTC_loop ; NO - loop | |
| 1280 bsf SSP1CON2,PEN ; YES - stop condition | |
| 1281 rcall WaitMSSP ; - wait for stop condition done | |
| 1282 WAITMS .1 ; - wait another 1 ms | |
| 1283 ; setup for read-back | |
| 1284 lfsr FSR2,buffer ; reset pointer to begin of send buffer | |
| 1285 movlw .63 ; initialize loop counter: 63 byte with ACK + 1 w/o ACK | |
| 1286 movwf i2c_temp2 | |
| 1287 ; address read-back | |
| 1288 bsf SSP1CON2,SEN ; start condition | |
| 560 | 1289 rcall WaitMSSP |
| 623 | 1290 movlw 0x51 ; address byte + read bit |
| 582 | 1291 movwf SSP1BUF ; control byte |
| 560 | 1292 rcall WaitMSSP |
| 1293 rcall I2C_WaitforACK | |
| 623 | 1294 ; read-back 64 bytes |
| 560 | 1295 I2C_update_OSTC_loop_read: |
| 623 | 1296 bsf SSP1CON2,RCEN ; enable receive mode |
| 560 | 1297 rcall WaitMSSP |
| 1298 movf SSP1BUF,W | |
| 623 | 1299 cpfseq POSTINC2 ; compare read-back byte with sent byte, equal? |
| 1300 bsf i2c_error_flag ; NO - not equal, set error flag | |
| 582 | 1301 bcf SSP1CON2,ACKDT |
| 623 | 1302 bsf SSP1CON2,ACKEN ; master acknowledge |
| 560 | 1303 rcall WaitMSSP |
| 623 | 1304 decfsz i2c_temp2,F ; decrement loop counter, became zero? |
| 1305 bra I2C_update_OSTC_loop_read ; NO - loop | |
| 560 | 1306 ; 1 w/o ACK |
| 623 | 1307 bsf SSP1CON2, RCEN ; YES - enable receive mode |
| 1308 rcall WaitMSSP ; - | |
| 1309 movf SSP1BUF,W ; - get 64th byte | |
| 1310 cpfseq POSTINC2 ; - compare read-back byte with sent byte, equal? | |
| 1311 bsf i2c_error_flag ; NO - not equal, set error flag | |
| 1312 bsf SSP1CON2,ACKDT ; - | |
| 1313 bsf SSP1CON2,ACKEN ; - master NOT acknowledge | |
| 1314 rcall WaitMSSP ; - | |
| 1315 bcf SSP1CON2,ACKDT ; - reset ACKDT flag | |
| 1316 ; stop | |
| 1317 bsf SSP1CON2,PEN ; stop condition | |
| 560 | 1318 rcall WaitMSSP |
| 1319 WAITMS .1 | |
| 623 | 1320 ; address commit |
| 1321 bsf SSP1CON2,SEN ; start condition | |
| 560 | 1322 rcall WaitMSSP |
| 623 | 1323 movlw 0x50 ; address byte + write bit |
| 582 | 1324 movwf SSP1BUF ; control byte |
| 560 | 1325 rcall WaitMSSP |
| 1326 rcall I2C_WaitforACK | |
| 623 | 1327 movlw 0x1F ; write command |
| 1328 movwf SSP1BUF ; data byte | |
| 560 | 1329 rcall WaitMSSP |
| 1330 rcall I2C_WaitforACK | |
| 623 | 1331 bsf SSP1CON2,PEN ; stop condition |
| 560 | 1332 rcall WaitMSSP |
| 623 | 1333 WAITMS .5 ; required waiting time |
| 1334 ; error check | |
| 1335 btfss i2c_error_flag ; did an error occur? | |
| 1336 retlw .0 ; NO - data transfered successfully | |
| 1337 retlw .255 ; YES - error in data transfer occurred | |
| 582 | 1338 |
| 604 | 1339 ENDIF |
| 1340 | |
| 623 | 1341 ;============================================================================= |
| 1342 | |
| 582 | 1343 END |
