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