Mercurial > public > hwos_code
annotate src/i2c.asm @ 656:8af5aefbcdaf default tip
Update to 3.31 beta
| author | heinrichsweikamp |
|---|---|
| date | Thu, 27 Nov 2025 18:32:58 +0100 |
| parents | c7b7b8a358cd |
| children |
| rev | line source |
|---|---|
| 0 | 1 ;============================================================================= |
| 2 ; | |
| 634 | 3 ; File i2c.asm * combined next generation V3.09.4b |
| 0 | 4 ; |
| 560 | 5 ; I2C Interface |
| 6 ; | |
| 654 | 7 ; Copyright (c) 2012, JD Gascuel, heinrichs weikamp gmbh, all right reserved. |
| 0 | 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 | |
| 643 | 40 ; |
| 41 ; Battery gauge | |
| 42 ; ------------- | |
| 43 ; LTC2942 read address (8-Bit): 0xC9 | |
| 44 ; LTC2942 write address (8-Bit): 0xC8 | |
| 656 | 45 ; |
| 46 ; Alternative Battery gauge | |
| 47 ; ------------- | |
| 48 ; LTC2959 read address (8-Bit): 0xC7 | |
| 49 ; LTC2959 write address (8-Bit): 0xC6 | |
| 643 | 50 ; |
| 51 ; Alternative pressure sensor | |
| 52 ; ----------- | |
| 53 ; MS5837 read address (8-Bit): 0xED | |
| 54 ; MS5837 write address (8-Bit): 0xEC | |
| 582 | 55 ; |
| 56 ; | |
| 57 | |
| 0 | 58 ; HISTORY |
| 59 ; 2012-08-22 : [mH] Creation | |
| 565 | 60 ; 2018-02-18 : [mH] Sync with hwOS Sport release |
| 0 | 61 |
| 62 | |
| 582 | 63 #include "hwos.inc" ; Mandatory header |
| 0 | 64 #include "wait.inc" |
| 113 | 65 #include "math.inc" |
| 631 | 66 #include "eeprom_rs232.inc" |
| 643 | 67 |
| 582 | 68 |
| 634 | 69 ;============================================================================= |
| 70 i2c CODE | |
| 582 | 71 ;============================================================================= |
| 0 | 72 |
| 634 | 73 |
| 0 | 74 |
| 634 | 75 ;----------------------------------------------------------------------------- |
| 76 ; Helper Function - get two Bytes and divide hi:lo/16 (signed) | |
| 77 ; | |
| 78 I2C_TwoBytesRX_div16: | |
| 79 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 80 movff SSP1BUF,hi ; copy data byte to hi | |
| 81 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 82 movff SSP1BUF,lo ; copy data byte to lo | |
| 83 I2C_TwoBytesRX_div16_2: ; divide hi:lo/16 (signed) only | |
| 582 | 84 bcf STATUS,C |
| 604 | 85 btfsc hi,7 ; copy sign bit to carry |
| 582 | 86 bsf STATUS,C |
| 87 rrcf hi ; /2 | |
| 88 rrcf lo | |
| 634 | 89 ;bra I2C_TwoBytesRX_div8 ; continue dividing hi:lo/8 (signed) |
| 90 | |
| 91 | |
| 92 ;----------------------------------------------------------------------------- | |
| 93 ; Helper Function - divide hi:lo/8 (signed) | |
| 94 ; | |
| 95 I2C_TwoBytesRX_div8: | |
| 582 | 96 bcf STATUS,C |
| 604 | 97 btfsc hi,7 ; copy sign bit to carry |
| 582 | 98 bsf STATUS,C |
| 99 rrcf hi ; /4 | |
| 100 rrcf lo | |
| 101 bcf STATUS,C | |
| 604 | 102 btfsc hi,7 ; copy sign bit to carry |
| 582 | 103 bsf STATUS,C |
| 104 rrcf hi ; /8 | |
| 105 rrcf lo | |
| 106 bcf STATUS,C | |
| 604 | 107 btfsc hi,7 ; copy sign bit to carry |
| 582 | 108 bsf STATUS,C |
| 109 rrcf hi ; /16 | |
| 110 rrcf lo | |
| 634 | 111 return ; done |
| 112 | |
| 0 | 113 |
| 634 | 114 ;----------------------------------------------------------------------------- |
| 115 ; Read Accelerometer | |
| 116 ; | |
| 582 | 117 global I2C_RX_accelerometer |
| 0 | 118 I2C_RX_accelerometer: |
| 628 | 119 btfsc compass_type3 ; compass3 ? |
| 120 bra I2C_RX_accelerometer_compass3 ; YES | |
| 604 | 121 btfsc compass_type2 ; compass2 ? |
| 122 bra I2C_RX_accelerometer_compass2 ; YES | |
| 628 | 123 btfsc compass_type1 ; compass1 ? |
| 604 | 124 bra I2C_RX_accelerometer_compass1 ; YES |
| 628 | 125 ;bra I2C_RX_accelerometer_compass0 ; NO - compass0 then |
| 126 | |
| 643 | 127 ;I2C_RX_accelerometer_compass0: |
| 656 | 128 rcall I2C_SEN ; start condition |
| 582 | 129 movlw 0x38 ; address |
| 634 | 130 rcall I2C_TX ; send byte |
| 131 movlw 0x00 ; ?? | |
| 132 rcall I2C_TX ; send byte | |
| 656 | 133 rcall I2C_RSEN ; repeated start condition |
| 582 | 134 movlw 0x39 ; address |
| 634 | 135 rcall I2C_TX ; send byte |
| 136 rcall I2C_OneByteRX ; get status byte | |
| 137 movf SSP1BUF,W ; copy status byte to WREG | |
| 158 | 138 |
| 582 | 139 ; Non-flipped screen: |
| 140 ; Chip orientation on the PCB requires | |
| 604 | 141 ; Original = corrected |
| 582 | 142 ; x = -x |
| 143 ; y = -y | |
| 144 ; z = -z | |
| 0 | 145 |
| 582 | 146 ; Flipped screen: |
| 147 ; Chip orientation on the PCB requires | |
| 604 | 148 ; Original = corrected |
| 582 | 149 ; x = x |
| 150 ; y = y | |
| 151 ; z = -z | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
152 |
| 604 | 153 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
| 623 | 154 btfsc flip_screen ; 180° rotation? |
| 604 | 155 bra I2C_RX_accelerometer2 ; YES |
| 634 | 156 comf hi ; NO - 16 bit sign change |
| 157 negf lo ; - .... | |
| 158 btfsc STATUS,C ; - carry to propagate? | |
| 159 incf hi,F ; - YES - do it | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
160 I2C_RX_accelerometer2: |
| 634 | 161 MOVII mpr,accel_DX ; copy result to accel_DX |
| 162 | |
| 623 | 163 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
| 164 btfsc flip_screen ; 180° rotation? | |
| 165 bra I2C_RX_accelerometer3 ; YES | |
| 634 | 166 comf hi ; NO - 16 bit sign change |
| 167 negf lo ; - ... | |
| 168 btfsc STATUS,C ; - carry to propagate? | |
| 169 incf hi,F ; YES - do it | |
| 170 I2C_RX_accelerometer3: | |
| 171 MOVII mpr,accel_DY ; copy result to accel_DY | |
| 172 | |
| 173 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 174 movff SSP1BUF,hi ; copy data byte to hi | |
| 656 | 175 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge |
| 634 | 176 movff SSP1BUF,lo ; copy data byte to lo |
| 177 rcall I2C_TwoBytesRX_div16_2 ; divide hi:lo/16 (signed) | |
| 623 | 178 comf hi ; 16 bit sign change |
| 634 | 179 negf lo ; ... |
| 623 | 180 btfsc STATUS,C ; carry to propagate? |
| 181 incf hi,F ; YES - do it | |
| 634 | 182 MOVII mpr,accel_DZ ; copy result to accel_DZ |
| 656 | 183 bra I2C_PEN ; stop condition |
| 0 | 184 |
| 185 | |
| 427 | 186 I2C_RX_accelerometer_compass1: |
| 656 | 187 rcall I2C_SEN ; start condition |
| 582 | 188 movlw 0x3C ; address |
| 634 | 189 rcall I2C_TX ; send byte |
| 582 | 190 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) |
| 634 | 191 rcall I2C_TX ; send byte |
| 656 | 192 rcall I2C_RSEN ; repeated start condition |
| 582 | 193 movlw 0x3D ; address |
| 634 | 194 |
| 195 I2C_RX_accelerometer_common: ; common part for compass 1,2 and 3 | |
| 196 rcall I2C_TX ; send byte | |
| 582 | 197 |
| 198 ; Non-flipped screen: | |
| 199 ; Chip orientation on the PCB requires | |
| 200 ; Original = Corrected | |
| 201 ; x = -x (Compass 1) | |
| 202 ; x = x (Compass 2) | |
| 203 ; y = -y | |
| 204 ; z = -z | |
| 205 | |
| 206 ; Flipped screen: | |
| 207 ; Chip orientation on the PCB requires | |
| 208 ; Original = Corrected | |
| 209 ; x = x (Compass 1) | |
| 210 ; x = -x (Compass 2) | |
| 211 ; y = y | |
| 212 ; z = -z | |
| 427 | 213 |
| 582 | 214 ; Dump the accelerator data |
| 634 | 215 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 582 | 216 movff SSP1BUF,lo ; accel_DX+0 |
| 634 | 217 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 218 movff SSP1BUF,hi ; accel_DX+1 |
| 582 | 219 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only |
| 220 btfss compass_type2 ; compass 2? | |
| 623 | 221 bra I2C_RX_accelerometer1_c1 ; NO - compass 1 |
| 582 | 222 ; compass 2 |
| 623 | 223 btfss flip_screen ; 180° rotation? |
| 224 bra I2C_RX_accelerometer2_c1 ; NO - continue with normal compass1 routines for Y and Z | |
| 582 | 225 ; flipped compass 2, negate x |
| 634 | 226 comf hi ; YES - 16 bit sign change |
| 227 negf lo ; - ... | |
| 228 btfsc STATUS,C ; - carry to propagate? | |
| 229 incf hi,F ; YES - do it | |
| 230 bra I2C_RX_accelerometer2_c1 ; - continue with normal compass1 routines for Y and Z | |
| 582 | 231 |
| 232 I2C_RX_accelerometer1_c1: | |
| 623 | 233 btfsc flip_screen ; 180° rotation? |
| 234 bra I2C_RX_accelerometer2_c1 ; YES | |
| 582 | 235 ; non-flipped compass 1, negate x |
| 634 | 236 comf hi ; NO - 16 bit sign change |
| 237 negf lo ; - ... | |
| 238 btfsc STATUS,C ; - carry to propagate? | |
| 239 incf hi,F ; YES - do it | |
| 427 | 240 I2C_RX_accelerometer2_c1: |
| 582 | 241 ; flipped compass 1, non-flipped compass 2 |
| 623 | 242 MOVII mpr,accel_DX ; copy result |
| 634 | 243 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 244 movff SSP1BUF,lo ; copy accel_DY+0 to lo | |
| 245 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 246 movff SSP1BUF,hi ; copy accel_DY+1 to hi | |
| 247 rcall I2C_TwoBytesRX_div16_2 ; divide hi:lo/16 (signed) only | |
| 623 | 248 btfsc flip_screen ; 180° rotation? |
| 249 bra I2C_RX_accelerometer3_c1 ; YES | |
| 634 | 250 comf hi ; NO - 16 bit sign change |
| 251 negf lo ; - ... | |
| 252 btfsc STATUS,C ; - carry to propagate? | |
| 253 incf hi,F ; YES - do it | |
| 427 | 254 I2C_RX_accelerometer3_c1: |
| 623 | 255 MOVII mpr,accel_DY ; copy result |
| 634 | 256 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 257 movff SSP1BUF,lo ; accel_DZ+0 |
| 656 | 258 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge |
| 623 | 259 movff SSP1BUF,hi ; accel_DZ+1 |
| 656 | 260 rcall I2C_PEN ; stop condition |
| 582 | 261 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only |
| 623 | 262 comf hi ; 16 bit sign change for Z |
| 634 | 263 negf lo ; ... |
| 623 | 264 btfsc STATUS,C ; carry to propagate? |
| 265 incf hi,F ; YES - do it | |
| 266 MOVII mpr,accel_DZ ; copy result | |
| 634 | 267 return ; done |
| 268 | |
| 582 | 269 |
| 560 | 270 I2C_RX_accelerometer_compass2: |
| 656 | 271 rcall I2C_SEN ; start condition |
| 582 | 272 movlw 0x32 ; address |
| 634 | 273 rcall I2C_TX ; send byte |
| 582 | 274 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) |
| 634 | 275 rcall I2C_TX ; send byte |
| 656 | 276 rcall I2C_RSEN ; repeated start condition |
| 582 | 277 movlw 0x33 ; address |
| 634 | 278 bra I2C_RX_accelerometer_common ; continue with common part |
| 624 | 279 |
| 280 I2C_RX_accelerometer_compass3: | |
| 656 | 281 rcall I2C_SEN ; start condition |
| 628 | 282 movlw 0x3A ; address |
| 634 | 283 rcall I2C_TX ; send byte |
| 628 | 284 movlw 0x28 ; 0x28 (OUT_X_L_A) |
| 634 | 285 rcall I2C_TX ; send byte |
| 656 | 286 rcall I2C_RSEN ; repeated start condition |
| 628 | 287 movlw 0x3B ; address |
| 634 | 288 bra I2C_RX_accelerometer_common ; continue with common part |
| 623 | 289 |
| 290 | |
| 634 | 291 |
| 292 ;----------------------------------------------------------------------------- | |
| 293 ; Read Compass | |
| 294 ; | |
| 623 | 295 IFDEF _compass |
| 0 | 296 |
| 582 | 297 global I2C_RX_compass |
| 0 | 298 I2C_RX_compass: |
| 628 | 299 btfsc compass_type3 ; compass 3 ? |
| 300 bra I2C_RX_compass3 ; YES | |
| 301 btfsc compass_type2 ; compass 2 ? | |
| 623 | 302 bra I2C_RX_compass2 ; YES |
| 628 | 303 btfsc compass_type1 ; compass 1 ? |
| 623 | 304 bra I2C_RX_compass1 ; YES |
| 628 | 305 ;bra I2C_RX_compass0 ; NO - compass 0 then |
| 306 | |
| 643 | 307 ;I2C_RX_compass0: |
| 656 | 308 rcall I2C_SEN ; start condition |
| 309 movlw 0x3C ; address + write bit | |
| 634 | 310 rcall I2C_TX ; send byte |
| 656 | 311 movlw 0x03 ; Point to Data Output X MSB Register (0x03) |
| 634 | 312 rcall I2C_TX ; send byte |
| 656 | 313 rcall I2C_PEN ; stop condition |
| 314 rcall I2C_SEN ; start condition | |
| 315 movlw 0x3D ; address + read bit | |
| 634 | 316 rcall I2C_TX ; send byte |
| 0 | 317 |
| 582 | 318 ; Compass IC sends data in following order: |
| 319 ; x MSB | |
| 320 ; x LSB | |
| 321 ; z MSB | |
| 322 ; z LSB | |
| 323 ; y MSB | |
| 324 ; y LSB | |
| 0 | 325 |
| 582 | 326 ; Non-flipped screen |
| 327 ; Chip orientation on the PCB requires | |
| 328 ; Original = Corrected | |
| 329 ; x = -y | |
| 330 ; z = z | |
| 331 ; y = x | |
| 0 | 332 |
| 582 | 333 ; Flipped screen |
| 334 ; Chip orientation on the PCB requires | |
| 335 ; Original = Corrected | |
| 336 ; x = y | |
| 337 ; z = z | |
| 338 ; y = -x | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
339 |
| 634 | 340 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 341 movff SSP1BUF,compass_DY+1 ; data byte |
| 634 | 342 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 343 movff SSP1BUF,compass_DY+0 ; data byte |
| 344 btfsc flip_screen ; 180° rotation? | |
| 345 bra I2C_RX_compass0_2 ; NO | |
| 346 banksel compass_DY ; YES - flip Y | |
| 347 comf compass_DY+1 ; - 16 bit sign change | |
| 582 | 348 negf compass_DY+0 |
| 623 | 349 btfsc STATUS,C ; - carry to propagate? |
| 350 incf compass_DY+1,F ; YES - do it | |
| 582 | 351 banksel common |
| 623 | 352 I2C_RX_compass0_2: |
| 634 | 353 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 354 movff SSP1BUF,compass_DZ+1 ; data byte |
| 634 | 355 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 356 movff SSP1BUF,compass_DZ+0 ; data byte |
| 634 | 357 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 358 movff SSP1BUF,compass_DX+1 ; data byte |
| 656 | 359 rcall I2C_RCEN ; enable receive mode |
| 623 | 360 movff SSP1BUF,compass_DX+0 ; data byte |
| 656 | 361 rcall I2C_PEN ; stop condition |
| 623 | 362 btfss flip_screen ; 180° rotation? |
| 363 return ; NO - done | |
| 364 banksel compass_DX ; YES - flip X | |
| 365 comf compass_DX+1 ; - 16 bit sign change | |
| 582 | 366 negf compass_DX+0 |
| 623 | 367 btfsc STATUS,C ; - carry to propagate? |
| 368 incf compass_DX+1,F ; YES - do it | |
| 634 | 369 banksel common ; back to bank common |
| 370 return ; done | |
| 371 | |
| 582 | 372 |
| 628 | 373 I2C_RX_compass1: ; compass type 1 |
| 656 | 374 rcall I2C_SEN ; start condition |
| 582 | 375 movlw 0x3C ; address |
| 634 | 376 rcall I2C_TX ; send byte |
| 582 | 377 movlw b'10001000' ; 0x08 with auto-increment (MSB=1) |
| 634 | 378 rcall I2C_TX ; send byte |
| 656 | 379 rcall I2C_RSEN ; repeated start condition |
| 582 | 380 movlw 0x3D ; address |
| 634 | 381 rcall I2C_TX ; send byte |
| 623 | 382 ;rcall WaitMSSP ; TODO needed? (mH) |
| 634 | 383 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 384 movff SSP1BUF,lo ; data byte |
| 634 | 385 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 386 movff SSP1BUF,hi ; data byte |
| 634 | 387 rcall I2C_TwoBytesRX_div8 ; divide hi,lo by 8 (signed) |
| 388 MOVII mpr,compass_DX ; copy result | |
| 623 | 389 btfss flip_screen ; 180° rotation? |
| 390 bra I2C_RX_compass1_1 ; NO | |
| 391 banksel compass_DX ; YES - flip X | |
| 392 comf compass_DX+1 ; - 16 bit sign change | |
| 582 | 393 negf compass_DX+0 |
| 623 | 394 btfsc STATUS,C ; - carry to propagate? |
| 395 incf compass_DX+1,F ; YES - do it | |
| 582 | 396 banksel common |
| 427 | 397 I2C_RX_compass1_1: |
| 634 | 398 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 399 movff SSP1BUF,lo ; data byte |
| 634 | 400 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 401 movff SSP1BUF,hi ; data byte |
| 634 | 402 rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
| 623 | 403 MOVII mpr,compass_DY |
| 404 btfss flip_screen ; 180° rotation? | |
| 405 bra I2C_RX_compass1_2 ; NO | |
| 406 banksel compass_DY ; YES - flip Y | |
| 407 comf compass_DY+1 ; - 16 bit sign change | |
| 634 | 408 negf compass_DY+0 ; - ... |
| 623 | 409 btfsc STATUS,C ; - carry to propagate? |
| 410 incf compass_DY+1,F ; YES - do it | |
| 411 banksel common | |
| 427 | 412 I2C_RX_compass1_2: |
| 634 | 413 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 414 movff SSP1BUF,lo ; data byte |
| 656 | 415 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge |
| 623 | 416 movff SSP1BUF,hi ; data byte |
| 634 | 417 rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
| 418 MOVII mpr,compass_DZ ; copy result | |
| 656 | 419 bra I2C_PEN ; stop condition |
| 643 | 420 |
| 560 | 421 |
| 634 | 422 |
| 628 | 423 I2C_RX_compass2: ; compass type 2 |
| 656 | 424 rcall I2C_SEN ; start condition |
| 582 | 425 movlw 0x3C ; address |
| 634 | 426 rcall I2C_TX ; send byte |
| 582 | 427 movlw 0xE8 ; 0x68 with auto-increment (MSB=1) |
| 634 | 428 rcall I2C_TX ; send byte |
| 656 | 429 rcall I2C_RSEN ; repeated start condition |
| 582 | 430 movlw 0x3D ; address |
| 634 | 431 rcall I2C_TX ; send byte |
| 628 | 432 I2C_RX_compass2_xx: ; compass 3 joins in here |
| 634 | 433 ; rcall WaitMSSP ; wait for TX to complete (not needed, as included in I2C_TX) |
| 434 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 623 | 435 movff SSP1BUF,lo ; data byte |
| 634 | 436 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 437 movff SSP1BUF,hi ; data byte |
| 634 | 438 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
| 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 | |
| 634 | 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 |
| 634 | 448 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 449 movff SSP1BUF,lo ; data byte |
| 634 | 450 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 451 movff SSP1BUF,hi ; data byte |
| 634 | 452 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
| 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 | |
| 634 | 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 | |
| 634 | 462 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
| 623 | 463 movff SSP1BUF,lo ; data byte |
| 656 | 464 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge |
| 623 | 465 movff SSP1BUF,hi ; data byte |
| 634 | 466 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
| 467 MOVII mpr,compass_DZ ; copy result | |
| 656 | 468 bra I2C_PEN ; stop condition |
| 643 | 469 |
| 582 | 470 |
| 634 | 471 |
| 628 | 472 I2C_RX_compass3: ; compass type 3 |
| 656 | 473 rcall I2C_SEN ; start condition |
| 628 | 474 movlw 0x3C ; address |
| 634 | 475 rcall I2C_TX ; send byte |
| 628 | 476 movlw 0xA8 ; 0x28 with auto-increment (MSB=1) |
| 634 | 477 rcall I2C_TX ; send byte |
| 656 | 478 rcall I2C_RSEN ; repeated start condition |
| 628 | 479 movlw 0x3D ; address |
| 634 | 480 rcall I2C_TX ; send byte |
| 628 | 481 bra I2C_RX_compass2_xx ; join with compass 2 code |
| 624 | 482 |
| 623 | 483 ENDIF ; _compass |
| 484 | |
| 634 | 485 |
| 623 | 486 ;----------------------------------------------------------------------------- |
| 634 | 487 ; Initialize Compass / Accelerometer Chip |
| 488 ; | |
| 582 | 489 global I2C_init_compass |
| 0 | 490 I2C_init_compass: |
| 656 | 491 bsf compass_present ; Set global compass flag |
| 634 | 492 bsf compass_enabled ; flag compass will be enabled |
| 493 bcf compass_type2 ; clear in preparation of chip detection | |
| 494 bcf compass_type3 ; ... | |
| 623 | 495 |
| 628 | 496 ; probe for compass 3 |
| 656 | 497 rcall I2C_SEN ; start condition |
| 628 | 498 movlw 0x3A ; address byte + write bit |
| 582 | 499 movwf SSP1BUF ; control byte |
| 634 | 500 rcall WaitMSSP ; wait for TX to complete |
| 656 | 501 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit! |
| 634 | 502 btfss SSP1CON2,ACKSTAT ; ACK received? |
| 503 bsf compass_type3 ; YES - ACK was send, compass 3 found | |
| 656 | 504 rcall I2C_PEN ; stop condition |
| 628 | 505 |
| 506 btfsc compass_type3 ; compass 3 found? | |
| 507 bra I2C_init_compass3 ; YES - initialize compass 3 | |
| 508 | |
| 509 ; probe for compass 2 | |
| 656 | 510 rcall I2C_SEN ; start condition |
| 628 | 511 movlw 0x32 ; address byte + write bit |
| 512 movwf SSP1BUF ; control byte | |
| 634 | 513 rcall WaitMSSP ; wait for TX to complete |
| 656 | 514 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit! |
| 515 btfss SSP1CON2,ACKSTAT ; ACK received? | |
| 634 | 516 bsf compass_type2 ; YES - ACK send, compass 2 found |
| 656 | 517 rcall I2C_PEN ; stop condition |
| 623 | 518 |
| 628 | 519 btfsc compass_type2 ; compass 2 found? |
| 520 bra I2C_init_compass2 ; YES - initialize compass 2 | |
| 521 | |
| 656 | 522 ; probe for compass 1 |
| 634 | 523 bsf compass_type1 ; assume compass 1 by default |
| 656 | 524 rcall I2C_SEN ; start condition |
| 582 | 525 movlw 0x3C ; address |
| 634 | 526 rcall I2C_TX ; send byte |
| 527 movlw 0x0F ; ?? | |
| 528 rcall I2C_TX ; send byte | |
| 656 | 529 rcall I2C_PEN ; stop condition |
| 530 rcall I2C_SEN ; start condition | |
| 582 | 531 movlw 0x3D ; address |
| 634 | 532 rcall I2C_TX ; send byte |
| 533 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 628 | 534 movlw 0x49 ; 0x49 = compass 1 |
| 634 | 535 cpfseq SSP1BUF ; 0x49 received? |
| 536 bcf compass_type1 ; NO - clear flag for compass 1 | |
| 656 | 537 rcall I2C_PEN ; stop condition |
| 582 | 538 |
| 628 | 539 btfsc compass_type1 ; compass 1 found? |
| 540 bra I2C_init_compass1 ; YES - initialize compass 1 | |
| 656 | 541 |
| 542 ; probe for compass 0 | |
| 543 bsf compass_type0 ; assume compass 0 by default | |
| 544 rcall I2C_SEN ; start condition | |
| 545 movlw 0x3C ; address + write bit | |
| 546 rcall I2C_TX ; send byte | |
| 547 movlw 0x0A ; Point to Identification Register A | |
| 548 rcall I2C_TX ; send byte | |
| 549 rcall I2C_PEN ; stop condition | |
| 550 rcall I2C_SEN ; start condition | |
| 551 movlw 0x3D ; address + read bit | |
| 552 rcall I2C_TX ; send byte | |
| 553 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
| 554 movlw b'01001000' ; Identification Register A must be "H" | |
| 555 cpfseq SSP1BUF ; Compare with received value | |
| 556 bcf compass_type0 ; Not equal -> Not compass 0 | |
| 557 rcall I2C_PEN ; stop condition | |
| 558 | |
| 559 btfsc compass_type0 ; compass 0 found? | |
| 560 bra I2C_init_compass0 ; YES - initialize compass 0 | |
| 561 ; ; no compass of any type found | |
| 562 bcf compass_present ; Delete global compass flag | |
| 563 return | |
| 628 | 564 |
| 634 | 565 |
| 628 | 566 I2C_init_compass0: |
| 567 ; magnetic | |
| 656 | 568 rcall I2C_SEN ; start condition |
| 582 | 569 movlw 0x3C ; address |
| 634 | 570 rcall I2C_TX ; send byte |
| 571 movlw 0x00 ; ?? | |
| 572 rcall I2C_TX ; send byte | |
| 623 | 573 movlw b'01101000' ; ConfigA: 3 Hz, 8 samples averaged |
| 634 | 574 rcall I2C_TX ; send byte |
| 623 | 575 movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) |
| 634 | 576 swapf i2c_temp1,F ; |
| 577 comf i2c_temp1,F ; | |
| 578 bcf STATUS,C ; | |
| 579 rlcf i2c_temp1 ; | |
| 580 movf i2c_temp1,W ; | |
| 581 rcall I2C_TX ; send byte | |
| 582 movlw b'00000000' ; select continuous mode | |
| 583 rcall I2C_TX ; send byte | |
| 656 | 584 rcall I2C_PEN ; stop condition |
| 634 | 585 |
| 628 | 586 ; accelerometer |
| 631 | 587 rcall I2C_sleep_accelerometer0 ; registers can only be changed in standby mode |
| 628 | 588 |
| 656 | 589 rcall I2C_SEN ; start condition |
| 628 | 590 movlw 0x38 ; address |
| 634 | 591 rcall I2C_TX ; send byte |
| 628 | 592 movlw 0x0E ; XYZ_DATA_CFG |
| 634 | 593 rcall I2C_TX ; send byte |
| 628 | 594 movlw b'00000000' ; high pass filter = 0, +/- 2 g range |
| 634 | 595 rcall I2C_TX ; send byte |
| 656 | 596 rcall I2C_PEN ; stop condition |
| 597 rcall I2C_SEN ; start condition | |
| 628 | 598 movlw 0x38 ; address |
| 634 | 599 rcall I2C_TX ; send byte |
| 628 | 600 movlw 0x2A ; CTRL_REG1 |
| 634 | 601 rcall I2C_TX ; send byte |
| 628 | 602 ; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode |
| 603 movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode | |
| 634 | 604 rcall I2C_TX ; send byte |
| 628 | 605 movlw b'00000010' ; CTRL_REG2: high-res in active mode |
| 634 | 606 rcall I2C_TX ; send byte |
| 656 | 607 rcall I2C_PEN ; stop condition |
| 628 | 608 |
| 656 | 609 rcall I2C_SEN ; start condition |
| 628 | 610 movlw 0x38 ; address |
| 634 | 611 rcall I2C_TX ; send byte |
| 628 | 612 movlw 0x2A ; CTRL_REG1 |
| 634 | 613 rcall I2C_TX ; send byte |
| 628 | 614 ; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode |
| 615 movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode | |
| 634 | 616 rcall I2C_TX ; send byte |
| 656 | 617 bra I2C_PEN ; stop condition |
| 643 | 618 |
| 0 | 619 |
| 628 | 620 |
| 427 | 621 I2C_init_compass1: |
| 656 | 622 rcall I2C_SEN ; start condition |
| 582 | 623 movlw 0x3C ; address |
| 634 | 624 rcall I2C_TX ; send byte |
| 582 | 625 movlw 0x9F ; 1F with auto-increment (MSB=1) |
| 634 | 626 rcall I2C_TX ; send byte |
| 582 | 627 movlw b'00000000' ; CTRL0 |
| 634 | 628 rcall I2C_TX ; send byte |
| 623 | 629 movlw b'00101111' ; CTRL1 (6.25 Hz, BDU=0, x,y,z = ON) |
| 634 | 630 rcall I2C_TX ; send byte |
| 623 | 631 movlw b'11000000' ; CTRL2 (50 Hz, +/- 2g) |
| 634 | 632 rcall I2C_TX ; send byte |
| 582 | 633 movlw b'00000000' ; CTRL3 |
| 634 | 634 rcall I2C_TX ; send byte |
| 582 | 635 movlw b'00000000' ; CTRL4 |
| 634 | 636 rcall I2C_TX ; send byte |
| 623 | 637 movlw b'01100100' ; CTRL5 HIGH res, 6.25 Hz |
| 634 | 638 rcall I2C_TX ; send byte |
| 623 | 639 movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) |
| 640 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) | |
| 582 | 641 dcfsnz i2c_temp1,F ; = 1? |
| 623 | 642 movlw b'01100000' ; YES - CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) |
| 582 | 643 dcfsnz i2c_temp1,F ; = 2? |
| 623 | 644 movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) |
| 582 | 645 dcfsnz i2c_temp1,F ; = 3? |
| 623 | 646 movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) |
| 582 | 647 dcfsnz i2c_temp1,F ; = 4? |
| 623 | 648 movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) |
| 582 | 649 dcfsnz i2c_temp1,F ; = 5? |
| 623 | 650 movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) |
| 582 | 651 dcfsnz i2c_temp1,F ; = 6? |
| 623 | 652 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) |
| 582 | 653 dcfsnz i2c_temp1,F ; = 7? |
| 623 | 654 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) |
| 634 | 655 rcall I2C_TX ; send byte |
| 582 | 656 movlw b'00000000' ; CTRL7 Continuous Mode |
| 634 | 657 rcall I2C_TX ; send byte |
| 656 | 658 bra I2C_PEN ; stop condition |
| 634 | 659 |
| 660 ; accelerometer initializes along with magnetic sensor | |
| 661 | |
| 582 | 662 |
| 560 | 663 I2C_init_compass2: |
| 628 | 664 ; magnetic |
| 656 | 665 rcall I2C_SEN ; start condition |
| 634 | 666 movlw 0x3C ; address |
| 667 rcall I2C_TX ; send byte | |
| 668 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) | |
| 669 rcall I2C_TX ; send byte | |
| 670 movlw b'10000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00 | |
| 671 rcall I2C_TX ; send byte | |
| 672 movlw b'00000011' ; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR) | |
| 673 rcall I2C_TX ; send byte | |
| 674 movlw b'00010000' ; CFG_REG_C_M BDU=1 0x62 0x57 | |
| 675 rcall I2C_TX ; send byte | |
| 656 | 676 rcall I2C_PEN ; stop condition |
| 634 | 677 |
| 628 | 678 ; accelerometer |
| 656 | 679 rcall I2C_SEN ; start condition |
| 628 | 680 movlw 0x32 ; address |
| 634 | 681 rcall I2C_TX ; send byte |
| 628 | 682 movlw 0x9F ; 1F with auto-increment (MSB=1) |
| 634 | 683 rcall I2C_TX ; send byte |
| 628 | 684 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) |
| 634 | 685 rcall I2C_TX ; send byte |
| 628 | 686 movlw b'00100111' ; CTRL_REG1_A (10Hz, x,y,z = ON) |
| 634 | 687 rcall I2C_TX ; send byte |
| 628 | 688 movlw b'00000000' ; CTRL_REG2_A |
| 634 | 689 rcall I2C_TX ; send byte |
| 628 | 690 movlw b'00000000' ; CTRL_REG3_A |
| 634 | 691 rcall I2C_TX ; send byte |
| 628 | 692 movlw b'00001000' ; CTRL_REG4_A (BDU=0, +/-2g, HR=1) |
| 634 | 693 rcall I2C_TX ; send byte |
| 628 | 694 ; movlw b'00000000' ; CTRL_REG5_A |
| 634 | 695 ; rcall I2C_TX ; send byte |
| 656 | 696 bra I2C_PEN ; stop condition |
| 582 | 697 |
| 628 | 698 |
| 624 | 699 I2C_init_compass3: |
| 628 | 700 ; magnetic |
| 656 | 701 rcall I2C_SEN ; start condition |
| 631 | 702 movlw 0x3C ; address |
| 634 | 703 rcall I2C_TX ; send byte |
| 631 | 704 movlw 0xA0 ; 0x20 with auto-increment (MSB=1) |
| 634 | 705 rcall I2C_TX ; send byte |
| 645 | 706 movlw b'01110000' ; CTRL_REG1_M (10Hz, X and Y in Ultra-high performance mode) 0x20 |
| 634 | 707 rcall I2C_TX ; send byte |
| 631 | 708 movlw b'01100000' ; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21 |
| 634 | 709 rcall I2C_TX ; send byte |
| 631 | 710 movlw b'01000000' ; CTRL_REG3_M (Continuous) 0x22 |
| 634 | 711 rcall I2C_TX ; send byte |
| 645 | 712 movlw b'00001100' ; CTRL_REG4_M (Z in Ultra-high performance mode) 0x23 |
| 634 | 713 rcall I2C_TX ; send byte |
| 631 | 714 movlw b'00000000' ; CTRL_REG5_M 0x24 |
| 634 | 715 rcall I2C_TX ; send byte |
| 631 | 716 movlw b'00000000' ; CTRL_REG5_M 0x24 |
| 634 | 717 rcall I2C_TX ; send byte |
| 656 | 718 rcall I2C_PEN ; stop condition |
| 631 | 719 |
| 628 | 720 ;accelerometer |
| 656 | 721 rcall I2C_SEN ; start condition |
| 631 | 722 movlw 0x3A ; address |
| 634 | 723 rcall I2C_TX ; send byte |
| 628 | 724 movlw 0x20 |
| 634 | 725 rcall I2C_TX ; send byte |
| 631 | 726 movlw b'10010111' ; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20 |
| 634 | 727 rcall I2C_TX ; send byte |
| 631 | 728 movlw b'00000000' ; CTRL_REG2_A 0x21 |
| 634 | 729 rcall I2C_TX ; send byte |
| 631 | 730 movlw b'00000000' ; CTRL_REG3_A 0x22 |
| 634 | 731 rcall I2C_TX ; send byte |
| 631 | 732 movlw b'11001100' ; CTRL_REG4_A 0x23 |
| 634 | 733 rcall I2C_TX ; send byte |
| 656 | 734 bra I2C_PEN ; stop condition |
| 735 | |
| 628 | 736 |
| 656 | 737 |
| 634 | 738 ;----------------------------------------------------------------------------- |
| 739 ; Deactivate Compass / Accelerometer | |
| 740 ; | |
| 582 | 741 global I2C_sleep_compass |
| 0 | 742 I2C_sleep_compass: |
| 628 | 743 btfss compass_enabled ; compass active? |
| 634 | 744 return ; NO - done |
| 623 | 745 bcf compass_enabled |
| 628 | 746 btfsc compass_type3 ; compass 3 ? |
| 624 | 747 bra I2C_sleep_compass3 ; YES |
| 628 | 748 btfsc compass_type2 ; compass 2 ? |
| 623 | 749 bra I2C_sleep_compass2 ; YES |
| 628 | 750 btfsc compass_type1 ; compass 1 ? |
| 623 | 751 bra I2C_sleep_compass1 ; YES |
| 628 | 752 ;bra I2C_sleep_compass0 ; NO - must be compass 0 then |
| 753 | |
| 634 | 754 |
| 560 | 755 I2C_sleep_compass0: |
| 628 | 756 ; magnetic |
| 656 | 757 rcall I2C_SEN ; start condition |
| 582 | 758 movlw 0x3C ; address |
| 634 | 759 rcall I2C_TX ; send byte |
| 760 movlw 0x00 ; ?? | |
| 761 rcall I2C_TX ; send byte | |
| 582 | 762 movlw b'01101000' ; ConfigA |
| 634 | 763 rcall I2C_TX ; send byte |
| 582 | 764 movlw b'00100000' ; ConfigB |
| 634 | 765 rcall I2C_TX ; send byte |
| 623 | 766 movlw b'00000010' ; idle mode |
| 634 | 767 rcall I2C_TX ; send byte |
| 656 | 768 rcall I2C_PEN ; stop condition |
| 631 | 769 |
| 634 | 770 I2C_sleep_accelerometer0: |
| 628 | 771 ; accelerometer |
| 656 | 772 rcall I2C_SEN ; start condition |
| 628 | 773 movlw 0x38 ; address |
| 634 | 774 rcall I2C_TX ; send byte |
| 628 | 775 movlw 0x2A ; CTRL_REG1 |
| 634 | 776 rcall I2C_TX ; send byte |
| 628 | 777 movlw b'00000000' ; standby mode |
| 634 | 778 rcall I2C_TX ; send byte |
| 656 | 779 bra I2C_PEN ; stop condition |
| 634 | 780 |
| 0 | 781 |
| 427 | 782 I2C_sleep_compass1: |
| 656 | 783 rcall I2C_SEN ; start condition |
| 582 | 784 movlw 0x3C ; address |
| 634 | 785 rcall I2C_TX ; send byte |
| 582 | 786 movlw 0x20 ; CTRL_REG1 |
| 634 | 787 rcall I2C_TX ; send byte |
| 623 | 788 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor power-down mode |
| 634 | 789 rcall I2C_TX ; send byte |
| 656 | 790 rcall I2C_PEN ; stop condition |
| 791 rcall I2C_SEN ; start condition | |
| 582 | 792 movlw 0x3C ; address |
| 634 | 793 rcall I2C_TX ; send byte |
| 582 | 794 movlw 0x26 ; CTRL_REG7 |
| 634 | 795 rcall I2C_TX ; send byte |
| 623 | 796 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode |
| 634 | 797 rcall I2C_TX ; send byte |
| 656 | 798 bra I2C_PEN ; stop condition |
| 634 | 799 |
| 800 ; accelerometer sleeps with magnetic sensor | |
| 631 | 801 |
| 560 | 802 |
| 803 I2C_sleep_compass2: | |
| 623 | 804 ; magnetic |
| 656 | 805 rcall I2C_SEN ; start condition |
| 623 | 806 movlw 0x3C ; address |
| 634 | 807 rcall I2C_TX ; send byte |
| 623 | 808 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) |
| 634 | 809 rcall I2C_TX ; send byte |
| 623 | 810 movlw b'00000011' ; CFG_REG_A_M 0x60 (idle mode)) |
| 634 | 811 rcall I2C_TX ; send byte |
| 623 | 812 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) |
| 634 | 813 rcall I2C_TX ; send byte |
| 623 | 814 movlw b'01010001' ; CFG_REG_C_M 0x62 |
| 634 | 815 rcall I2C_TX ; send byte |
| 623 | 816 movlw b'00000000' ; INT_CTRL_REG_M 0x63 |
| 634 | 817 rcall I2C_TX ; send byte |
| 656 | 818 rcall I2C_PEN ; stop condition |
| 582 | 819 |
| 623 | 820 ; accelerometer |
| 656 | 821 rcall I2C_SEN ; start condition |
| 623 | 822 movlw 0x32 ; address |
| 634 | 823 rcall I2C_TX ; send byte |
| 623 | 824 movlw 0x9F ; 1F with auto-increment (MSB=1) |
| 634 | 825 rcall I2C_TX ; send byte |
| 623 | 826 movlw b'00000000' ; TEMP_CFG_REG_A 0x1F (temp sensor off) |
| 634 | 827 rcall I2C_TX ; send byte |
| 623 | 828 movlw b'00000000' ; CTRL_REG1_A 0x20 (all off) |
| 634 | 829 rcall I2C_TX ; send byte |
| 656 | 830 bra I2C_PEN ; stop condition |
| 634 | 831 |
| 623 | 832 |
| 628 | 833 I2C_sleep_compass3: |
| 834 ; magnetic | |
| 656 | 835 rcall I2C_SEN ; start condition |
| 628 | 836 movlw 0x3C ; address |
| 634 | 837 rcall I2C_TX ; send byte |
| 628 | 838 movlw 0xA2 ; 0x22 with auto-increment (MSB=1) |
| 634 | 839 rcall I2C_TX ; send byte |
| 628 | 840 movlw b'01000010' ; CTRL_REG3_M (power-down) 0x22 |
| 634 | 841 rcall I2C_TX ; send byte |
| 656 | 842 rcall I2C_PEN ; stop condition |
| 628 | 843 |
| 844 ; accelerometer | |
| 656 | 845 rcall I2C_SEN ; start condition |
| 628 | 846 movlw 0x3A ; address |
| 634 | 847 rcall I2C_TX ; send byte |
| 624 | 848 movlw 0x20 |
| 634 | 849 rcall I2C_TX ; send byte |
| 628 | 850 movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20 |
| 634 | 851 rcall I2C_TX ; send byte |
| 656 | 852 bra I2C_PEN ; stop condition |
| 853 | |
| 854 | |
| 855 ;----------------------------------------------------------------------------- | |
| 856 ; Helper Function - receive 1 Byte with Not-Acknowledge | |
| 857 ; | |
| 858 I2C_OneByteRX_NACK: | |
| 859 rcall I2C_RCEN ; enable receive mode | |
| 860 bsf SSP1CON2,ACKDT ; set ACKDT flag | |
| 861 rcall I2C_ACKEN ; send master acknowledge | |
| 862 bcf SSP1CON2,ACKDT ; reset ACKDT flag | |
| 863 return | |
| 634 | 864 |
| 0 | 865 |
| 634 | 866 ;----------------------------------------------------------------------------- |
| 656 | 867 ; Helper Function - receive 1 Byte with Acknowledge |
| 868 ; | |
| 869 I2C_OneByteRX: | |
| 870 rcall I2C_RCEN ; enable receive mode | |
| 871 bra I2C_ACKEN ; send master acknowledge | |
| 872 | |
| 873 ;----------------------------------------------------------------------------- | |
| 874 ; Helper Function - send 1 Byte, wait for end of transmission and check ackn | |
| 875 ; add WREG to checksum byte first | |
| 876 I2C_TX_CHKSUM: | |
| 877 addwf sub_a+0,F ; add to checksum | |
| 878 ; bra I2C_TX | |
| 879 ;----------------------------------------------------------------------------- | |
| 880 ; Helper Function - send 1 Byte, wait for end of transmission and check ackn | |
| 881 ; | |
| 882 I2C_TX: | |
| 883 movwf SSP1BUF ; put byte to be sent into TX buffer | |
| 884 btfss i2c_error_flag_lock ; vault in use already? | |
| 885 movff WREG,i2c_error_vault+0 ; NO, Store address | |
| 886 rcall WaitMSSP ; wait for TX to complete | |
| 887 bra I2C_Check_ACK ; check for acknowledge by receiver and return | |
| 888 | |
| 889 | |
| 890 ;----------------------------------------------------------------------------- | |
| 891 ; Helper Function - I2C Start Condition | |
| 892 ; | |
| 893 I2C_SEN: | |
| 894 bsf SSP1CON2,SEN ; start condition | |
| 895 bra WaitMSSP ; wait for TX to complete (And return) | |
| 896 | |
| 897 ;----------------------------------------------------------------------------- | |
| 898 ; Helper Function - I2C Repeated Start Condition | |
| 899 ; | |
| 900 I2C_RSEN: | |
| 901 bsf SSP1CON2,RSEN ; repeated start condition | |
| 902 bra WaitMSSP ; wait for TX to complete (And return) | |
| 903 | |
| 904 | |
| 905 ;----------------------------------------------------------------------------- | |
| 906 ; Helper Function - I2C Stop Condition | |
| 907 ; | |
| 908 I2C_PEN: | |
| 909 bsf SSP1CON2,PEN ; stop condition | |
| 910 rcall WaitMSSP ; wait for TX to complete (And return) | |
| 911 I2C_WAIT_100US: | |
| 912 ; add ~100µs bus free time (min. 66µs recommended for LTC2959) | |
| 913 ; Remark: not exact: 122µs +/- 30.5 µs + worst case ISR latency | |
| 914 setf TMR5H ; initialize timer 5, high byte first | |
| 915 movlw .255-.4 ; 4 x 31.5 µs = 126µs, min: 94,5µs | |
| 916 movwf TMR5L ; initialize timer 5, low byte thereafter | |
| 917 bcf PIR5,TMR5IF ; clear timer 5 overrun flag | |
| 918 I2C_PEN_Loop: | |
| 919 btfss PIR5,TMR5IF ; did timer 5 overrun? | |
| 920 bra I2C_PEN_Loop ; NO - repeat inner loop | |
| 921 return | |
| 922 | |
| 923 ;----------------------------------------------------------------------------- | |
| 924 ; Helper Function - Master Acknowledge | |
| 925 ; | |
| 926 I2C_ACKEN: | |
| 927 bsf SSP1CON2,ACKEN ; master acknowledge | |
| 928 bra WaitMSSP ; wait for TX to complete (And return) | |
| 929 | |
| 930 ;----------------------------------------------------------------------------- | |
| 931 ; Helper Function - Enable reeive mode | |
| 932 ; | |
| 933 I2C_RCEN: | |
| 934 bsf SSP1CON2,RCEN ; enable receive mode | |
| 935 bra WaitMSSP ; wait for TX to complete (And return) | |
| 936 | |
| 937 ;----------------------------------------------------------------------------- | |
| 634 | 938 ; Helper Function - wait for TX to complete |
| 939 ; | |
| 615 | 940 WaitMSSP: |
| 656 | 941 btfss i2c_error_flag_lock ; vault in use already? |
| 942 movff SSP1BUF,i2c_error_vault+1 ; NO, store value | |
| 943 btfss i2c_error_flag_lock ; vault in use already? | |
| 944 movff SSP1CON2,i2c_error_vault+2 ; NO, store value | |
| 634 | 945 clrf i2c_temp1 ; wait for max 256 loops |
| 946 WaitMSSP_loop: | |
| 947 decfsz i2c_temp1,F ; decrement loop counter, timeout? | |
| 948 bra WaitMSSP2 ; NO | |
| 949 bra I2CFail ; YES | |
| 615 | 950 WaitMSSP2: |
| 634 | 951 btfss PIR1,SSP1IF ; TX completed? |
| 952 bra WaitMSSP_loop ; NO - loop | |
| 953 bcf PIR1,SSP1IF ; YES - clear TX completion flag | |
| 954 return ; - done | |
| 955 | |
| 615 | 956 |
| 634 | 957 ;----------------------------------------------------------------------------- |
| 650 | 958 ; Helper Function - Master NOT acknowledge and Stop |
| 959 ; | |
| 960 I2C_MasterNotAckStop: | |
| 961 bsf SSP1CON2,ACKDT ; set ACKDT flag | |
| 656 | 962 rcall I2C_ACKEN ; send master NOT acknowledge |
| 650 | 963 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
| 964 | |
| 656 | 965 bra I2C_PEN ; stop condition |
| 650 | 966 |
| 967 ;----------------------------------------------------------------------------- | |
| 634 | 968 ; Helper Function - check for Acknowledge by Receiver |
| 969 ; | |
| 970 I2C_Check_ACK: | |
| 628 | 971 btfss SSP1CON2,ACKSTAT ; ACK received from slave? |
| 634 | 972 return ; YES - done |
| 973 ;bra I2CFail ; NO - do some clean up | |
| 974 | |
| 975 | |
| 976 ;----------------------------------------------------------------------------- | |
| 977 ; Helper Function - clean up I2C Interface after missing Acknowledge | |
| 978 ; | |
| 979 I2CFail: | |
| 980 bsf active_reset_ostc_rx ; reset RX circuitry (which may be the cause for the hang up) | |
| 981 rcall I2CReset ; reset I2C | |
| 982 bcf PIR1,SSP1IF ; clear TX completion flag | |
| 983 bsf i2c_error_flag ; set error flag | |
| 656 | 984 bsf i2c_error_flag_lock ; lock the error vault |
| 634 | 985 bcf active_reset_ostc_rx ; release reset from RX circuitry |
| 643 | 986 ; bcf i2c_busy_temperature |
| 987 ; bcf i2c_busy_pressure | |
| 634 | 988 return ; done |
| 615 | 989 |
| 634 | 990 |
| 991 ;----------------------------------------------------------------------------- | |
| 992 ; Helper Function - Reset I2C Module | |
| 993 ; | |
| 994 ; recover in case something went wrong, i.g. slave holds SDA low | |
| 995 ; | |
| 656 | 996 global I2CReset |
| 634 | 997 I2CReset: |
| 998 clrf SSP1CON1 ; reset entire module | |
| 999 clrf SSP1CON2 ; ... | |
| 1000 clrf SSP1STAT ; ... | |
| 1001 bcf TRISC,3 ; SCL as OUTPUT | |
| 1002 bsf TRISC,4 ; SDA as input | |
| 1003 bcf PORTC,3 ; SCL = 0 | |
| 1004 movlw d'9' ; clock-out 9 clock cycles manually | |
| 1005 movwf i2c_temp1 ; ... | |
| 615 | 1006 I2CReset_1: |
| 1007 bsf PORTC,3 ; SCL = 1 | |
| 634 | 1008 nop ; pause for 4 CPU cycles |
| 1009 nop ; ... | |
| 1010 nop ; ... | |
| 1011 nop ; ... | |
| 615 | 1012 btfsc PORTC,4 ; SDA = 1 ? |
| 634 | 1013 bra I2CReset_2 ; YES - SDA has been released from slave |
| 615 | 1014 bcf PORTC,3 ; NO - set SCL = 0 |
| 634 | 1015 nop ; - pause for 2 CPU cycles |
| 1016 nop ; - ... | |
| 1017 bcf PORTC,3 ; - SCL = 0 | |
| 1018 nop ; - pause for 2 CPU cycles | |
| 1019 nop ; - ... | |
| 1020 decfsz i2c_temp1,F ; - clock counter, all cycles done? | |
| 1021 bra I2CReset_1 ; NO - loop | |
| 615 | 1022 I2CReset_2: |
| 634 | 1023 bsf TRISC,3 ; SCL as input |
| 1024 clrf SSP1CON1 ; setup I2C mode | |
| 656 | 1025 rcall I2C_WAIT_100US ; ISR-Safe 100µs wait |
| 634 | 1026 movlw b'00000000' ; enable slew rate control |
| 1027 movwf SSP1STAT ; ... | |
| 1028 movlw b'00101000' ; configure I2C module | |
| 1029 movwf SSP1CON1 ; ... | |
| 1030 movlw b'00000000' ; ... | |
| 1031 movwf SSP1CON2 ; ... | |
| 643 | 1032 movlw i2c_speed_value |
| 634 | 1033 movwf SSP1ADD ; ... |
| 656 | 1034 rcall I2C_WAIT_100US ; ISR-Safe 100µs wait |
| 1035 movlw .1 | |
| 1036 addwf i2c_error_counter+0 | |
| 1037 movlw .0 | |
| 1038 addwfc i2c_error_counter+1 ; +1 on the error counter | |
| 1039 btfss press_sensor_type ; =1: pressure sensor MS5837, =0: Pressure sensor MS5541 | |
| 1040 return ; MS5541, Done. | |
| 1041 ; reset the sensor | |
| 1042 rcall I2C_SEN ; start condition | |
| 1043 movlw 0xEC ; address byte + write bit | |
| 1044 rcall I2C_TX ; send byte | |
| 1045 movlw 0x1E | |
| 1046 rcall I2C_TX ; send byte | |
| 1047 rcall I2C_PEN ; stop condition | |
| 1048 WAITMS .5 ; 2.8ms according to datasheet | |
| 1049 return ; done | |
| 623 | 1050 |
| 1051 | |
| 634 | 1052 ;----------------------------------------------------------------------------- |
| 1053 ; Helper Function - Initialize Gauge IC again after an UVLO Event | |
| 1054 ; | |
| 656 | 1055 battery_gauge_init_again: |
| 1056 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1057 return | |
| 655 | 1058 rcall I2CReset |
| 623 | 1059 movlw 0x02 ; point to accumulated charge registers |
| 634 | 1060 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
| 623 | 1061 movff battery_accumulated_charge+1,SSP1BUF ; data byte |
| 634 | 1062 rcall WaitMSSP ; wait for TX to complete |
| 1063 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 623 | 1064 movff battery_accumulated_charge+0,SSP1BUF ; data byte |
| 634 | 1065 rcall WaitMSSP ; wait for TX to complete |
| 1066 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 656 | 1067 rcall I2C_PEN ; stop condition |
| 634 | 1068 MOVII battery_accumulated_charge,sub_a ; copy result to sub_a |
| 656 | 1069 ;bra battery_gauge_init ; and initialize again... |
| 560 | 1070 |
| 628 | 1071 |
| 634 | 1072 ;----------------------------------------------------------------------------- |
| 1073 ; Initialize Gauge IC | |
| 1074 ; | |
| 656 | 1075 global battery_gauge_init |
| 1076 battery_gauge_init: | |
| 1077 movlw 0x01 ; point to control reg B / ADC Control | |
| 1078 rcall I2C_TX_GAUGE ; send byte to the gauge IC | |
| 1079 movlw b'11111000' ; automatic conversion every two seconds (LT2942) | |
| 1080 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1081 movlw b'00111000' ; ADC Mode to "Smart Sleep" (converts V, I, T every 52 seconds (tolerance < ±5%)) (LTC2959) | |
| 1082 rcall I2C_TX ; send byte | |
| 1083 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1084 movlw b'01010000' ; 20µV deadband | |
| 1085 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1086 rcall I2C_TX ; send one byte more for the LTC2959 | |
| 1087 bra I2C_PEN ; stop condition | |
| 628 | 1088 |
| 634 | 1089 ;----------------------------------------------------------------------------- |
| 1090 ; Read Gauge IC - Status Register | |
| 1091 ; | |
| 113 | 1092 global lt2942_get_status |
| 634 | 1093 lt2942_get_status: |
| 656 | 1094 bcf battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 |
| 1095 bcf battery_gauge_available ; clear flag on default | |
| 643 | 1096 |
| 656 | 1097 ; try LTC2942 |
| 1098 rcall I2C_SEN ; start condition | |
| 1099 movlw 0xC8 ; address byte + Write bit | |
| 1100 movwf SSP1BUF ; put byte to be sent into TX buffer | |
| 643 | 1101 rcall WaitMSSP ; wait for TX to complete |
| 656 | 1102 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit! |
| 1103 btfss SSP1CON2,ACKSTAT ; ACK received from slave? | |
| 1104 bsf battery_gauge_available ; YES - set flag | |
| 1105 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop | |
| 1106 btfsc battery_gauge_available ; found? | |
| 1107 return ; YES - done | |
| 1108 | |
| 1109 ; try LTC2959 | |
| 1110 rcall I2C_SEN ; start condition | |
| 1111 movlw 0xC6 ; address byte + Write bit | |
| 1112 movwf SSP1BUF ; put byte to be sent into TX buffer | |
| 643 | 1113 rcall WaitMSSP ; wait for TX to complete |
| 656 | 1114 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit! |
| 1115 btfss SSP1CON2,ACKSTAT ; ACK received from slave? | |
| 1116 bsf battery_gauge_available ; YES - set flag | |
| 1117 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop | |
| 1118 btfsc battery_gauge_available ; found? | |
| 1119 bsf battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1120 return ; NO, return | |
| 113 | 1121 |
| 634 | 1122 ;----------------------------------------------------------------------------- |
| 1123 ; Read Gauge IC - Voltage | |
| 1124 ; | |
| 113 | 1125 global lt2942_get_voltage |
| 634 | 1126 lt2942_get_voltage: |
| 656 | 1127 |
| 1128 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1129 bra LTC2959_get_voltage ; use new IC | |
| 1130 | |
| 623 | 1131 movlw 0x08 ; point to voltage registers |
| 634 | 1132 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
| 1133 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
| 656 | 1134 rcall I2C_ACKEN ; send master acknowledge |
| 634 | 1135 movff SSP1BUF,xA+1 ; copy received byte to xA+1 |
| 656 | 1136 rcall I2C_RCEN ; enable receive mode |
| 634 | 1137 movff SSP1BUF,xA+0 ; copy received byte to xA+0 |
| 650 | 1138 |
| 1139 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop | |
| 643 | 1140 |
| 623 | 1141 ; convert voltage from raw value to Volt |
| 1142 MOVLI .6000,xB ; load conversion multiplicand into xB | |
| 1143 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
| 1144 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
| 656 | 1145 movff xC+2,xC+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result |
| 1146 movff xC+3,xC+1 ; use xC+0 and xC+1 as temp | |
| 615 | 1147 |
| 656 | 1148 movlw .4 ; battery voltage < 4*256mV (1.024)? |
| 1149 cpfslt xC+1 ; < 1024 mV ? | |
| 1150 bra lt2942_get_voltage_check_high ; NO - Continue checking | |
| 1151 bra battery_gauge_init_again ; YES - initialize gauge and return (and leave batt_voltage:2 untouched) | |
| 1152 | |
| 1153 lt2942_get_voltage_check_high: | |
| 1154 movlw .17 ; battery voltage >= 17*256mV (4.352V)? | |
| 1155 cpfslt xC+1 ; - ... ? | |
| 1156 bra battery_gauge_init_again ; YES - initialize gauge and return (and leave batt_voltage:2 untouched) | |
| 1157 ; NO - done | |
| 1158 movff xC+0, batt_voltage+0 | |
| 1159 movff xC+1, batt_voltage+1 | |
| 1160 bra lt2942_get_accumulated_charge ; - read coulomb counter (And return) | |
| 1161 | |
| 1162 LTC2959_get_voltage: | |
| 1163 movlw 0x0F ; point to voltage registers | |
| 1164 rcall I2C_TX_GAUGE ; send byte to the gauge IC | |
| 1165 rcall I2C_RX_GAUGE ; receive byte from the Gauge IC | |
| 1166 rcall I2C_ACKEN ; send master acknowledge | |
| 1167 movff SSP1BUF,xA+1 ; copy received byte to xA+1 | |
| 1168 rcall I2C_RCEN ; enable receive mode | |
| 1169 movff SSP1BUF,xA+0 ; copy received byte to xA+0 | |
| 1170 | |
| 1171 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop | |
| 1172 | |
| 1173 ; convert voltage from raw value to mV | |
| 1174 MOVLI .62600,xB ; load conversion multiplicand into xB | |
| 1175 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
| 1176 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
| 1177 ;movff xC+2,xC+0 ; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result | |
| 1178 ;movff xC+3,xC+1 ; use xC+0 and xC+1 as temp | |
| 1179 | |
| 1180 movff xC+2, batt_voltage+0 | |
| 1181 movff xC+3, batt_voltage+1 | |
| 1182 rcall lt2942_get_accumulated_charge ; - read coulomb counter (And return) | |
| 1183 | |
| 1184 return ; done | |
| 623 | 1185 |
| 615 | 1186 |
| 634 | 1187 ;----------------------------------------------------------------------------- |
| 1188 ; Read Gauge IC - Temperature | |
| 1189 ; | |
| 623 | 1190 global lt2942_get_temperature |
| 1191 lt2942_get_temperature: ; read battery temperature | |
| 656 | 1192 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 |
| 1193 bra LTC2959_get_temperature | |
| 1194 | |
| 623 | 1195 movlw 0x0C ; point to temperature register |
| 643 | 1196 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
| 1197 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
| 656 | 1198 rcall I2C_ACKEN ; send master acknowledge |
| 623 | 1199 movff SSP1BUF,xA+1 ; store raw temperature, high byte |
| 656 | 1200 rcall I2C_RCEN ; enable receive mode |
| 623 | 1201 movff SSP1BUF,xA+0 ; store raw temperature, low byte |
| 650 | 1202 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 623 | 1203 |
| 656 | 1204 ; convert temperature from raw value to Kelvin in 0.1K |
| 623 | 1205 MOVLI .6000,xB ; load conversion multiplicand into xB |
| 1206 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
| 1207 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
| 1208 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 | |
| 1209 movff xC+3,battery_temperature+1 ; ... | |
| 1210 | |
| 656 | 1211 lt2942_get_temperature_common: |
| 634 | 1212 ; check if battery is being charged right now |
| 623 | 1213 btfss cc_active ; in CC charging mode? |
| 1214 return ; NO - not charging, done | |
| 1215 | |
| 640 | 1216 ; ignore false readings (>125°C) |
| 1217 movlw LOW .3307 | |
| 1218 movwf sub_a+0 | |
| 1219 movlw HIGH .3307 | |
| 1220 movwf sub_a+1 | |
| 1221 MOVII battery_temperature, sub_b | |
| 1222 call cmpU16 ; sub_a - sub_b (with UNSIGNED values) | |
| 1223 btfsc neg_flag ; result negative? | |
| 1224 return ; YES - temperature > 125°C, not possible here. Skip test. | |
| 1225 | |
| 623 | 1226 ; check for over-temperature while charging |
| 1227 MOVLI max_battery_charge_temp,sub_a | |
| 1228 MOVII battery_temperature, sub_b | |
| 1229 call cmpU16 ; sub_a - sub_b (with UNSIGNED values) | |
| 1230 btfss neg_flag ; result negative? | |
| 1231 return ; NO - temperature <= threshold, ok, done | |
| 640 | 1232 return |
| 623 | 1233 ; YES - too hot, disable charging circuitry |
| 1234 bsf charge_disable ; - set charging-inhibit signal | |
| 1235 bcf charge_enable ; - activate charging-inhibit signal | |
| 1236 bsf battery_overtemp ; - flag that the battery charging over-temperature protection has tripped | |
| 656 | 1237 return ; - done |
| 623 | 1238 |
| 656 | 1239 LTC2959_get_temperature: |
| 1240 return | |
| 1241 | |
| 113 | 1242 |
| 634 | 1243 ;----------------------------------------------------------------------------- |
| 1244 ; Read Gauge IC - Read State of Charge | |
| 1245 ; | |
| 623 | 1246 lt2942_get_accumulated_charge: ; read accumulated charge and compute percent |
| 656 | 1247 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LTC2942 |
| 1248 bra LTC2959_get_accumulated_charge | |
| 1249 | |
| 1250 ; old LTC2942 | |
| 623 | 1251 movlw 0x00 ; point to status register |
| 634 | 1252 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
| 1253 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
| 656 | 1254 rcall I2C_ACKEN ; send master acknowledge |
| 634 | 1255 movff SSP1BUF,gauge_status_byte ; copy received byte to gauge_status_byte |
| 466 | 1256 |
| 656 | 1257 rcall I2C_RCEN ; enable receive mode |
| 1258 movf SSP1BUF,W ; dump to WREG (Control) | |
| 1259 rcall I2C_ACKEN ; send master acknowledge | |
| 582 | 1260 |
| 656 | 1261 rcall I2C_RCEN ; enable receive mode |
| 634 | 1262 movff SSP1BUF,sub_a+1 ; copy received byte to sub_a+1 |
| 656 | 1263 rcall I2C_ACKEN ; send master acknowledge |
| 582 | 1264 |
| 656 | 1265 rcall I2C_RCEN ; enable receive mode |
| 634 | 1266 movff SSP1BUF,sub_a+0 ; copy received byte to sub_a+0 |
| 650 | 1267 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 113 | 1268 |
| 656 | 1269 lt2942_get_accumulated_charge2: |
| 623 | 1270 btfsc gauge_status_byte,0 ; UVLO event ? |
| 656 | 1271 rcall battery_gauge_init_again ; YES - do an re-initialization |
| 623 | 1272 MOVII sub_a,battery_accumulated_charge ; save raw value |
| 656 | 1273 ; Compute batt_percent = (charge - battery_offset) / capacity_xxxxxx |
| 634 | 1274 MOVII battery_offset,sub_b ; get battery offset |
| 582 | 1275 call subU16 ; sub_c = sub_a - sub_b (with signed values) |
| 634 | 1276 clrf batt_percent ; default batt_percent to zero |
| 582 | 1277 btfsc neg_flag ; result negative? |
| 623 | 1278 bra lt2942_set_to_zero_percent ; YES - keep LT2942 at zero percent and return |
| 113 | 1279 |
| 623 | 1280 ; > zero, set batt_percent properly |
| 634 | 1281 MOVII sub_c,xA ; copy net charge to xA |
| 1282 MOVII battery_capacity,xB ; get battery capacity into xB | |
| 604 | 1283 call div16x16 ; xC = xA / xB with xA as remainder |
| 634 | 1284 movff xC+0,batt_percent ; result is battery percentage |
| 628 | 1285 movlw .100 ; max. value is 100 % |
| 1286 cpfslt batt_percent ; batt_percent < 100 % ? | |
| 1287 movwf batt_percent ; NO - limit to 100 % | |
| 656 | 1288 movlw battery_cycle_counter_unlock |
| 1289 cpfsgt batt_percent ; < threshold ? | |
| 654 | 1290 bcf lock_cycle_counter ; Yes, unlock cycle counter |
| 631 | 1291 return ; done |
| 113 | 1292 |
| 656 | 1293 LTC2959_get_accumulated_charge: |
| 1294 movlw 0x00 ; point to status register | |
| 1295 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC | |
| 1296 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
| 1297 rcall I2C_ACKEN ; send master acknowledge | |
| 1298 movff SSP1BUF,gauge_status_byte ; copy received byte to gauge_status_byte | |
| 1299 | |
| 1300 rcall I2C_RCEN ; enable receive mode | |
| 1301 movf SSP1BUF,W ; dump to WREG (ADC Control) | |
| 1302 rcall I2C_ACKEN ; send master acknowledge | |
| 1303 | |
| 1304 rcall I2C_RCEN ; enable receive mode | |
| 1305 movf SSP1BUF,W ; dump to WREG (Coulumb Counter Control) | |
| 1306 rcall I2C_ACKEN ; send master acknowledge | |
| 1307 | |
| 1308 rcall I2C_RCEN ; enable receive mode | |
| 1309 movff SSP1BUF,xC+3 ; copy received byte to xC+3 | |
| 1310 rcall I2C_ACKEN ; send master acknowledge | |
| 1311 | |
| 1312 rcall I2C_RCEN ; enable receive mode | |
| 1313 movff SSP1BUF,xC+2 ; copy received byte to xC+2 | |
| 1314 rcall I2C_ACKEN ; send master acknowledge | |
| 1315 | |
| 1316 rcall I2C_RCEN ; enable receive mode | |
| 1317 movff SSP1BUF,xC+1 ; copy received byte to xC+1 | |
| 1318 rcall I2C_ACKEN ; send master acknowledge | |
| 1319 | |
| 1320 rcall I2C_RCEN ; enable receive mode | |
| 1321 movff SSP1BUF,xC+0 ; copy received byte to xC+0 | |
| 1322 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop | |
| 1323 | |
| 1324 MOVLI .159,xB ; 159,4745717 (0,085mAh/533nAh) | |
| 1325 call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder | |
| 1326 | |
| 1327 ; clamp to 100% here | |
| 1328 tstfsz xC+2 ; Devision result > 0xFFFF | |
| 1329 setf xC+0 ; Yes, make sure xC:2 is 0xFFFF | |
| 1330 tstfsz xC+2 ; Devision result > 0xFFFF | |
| 1331 setf xC+1 ; Yes, make sure xC:2 is 0xFFFF | |
| 1332 | |
| 1333 movff xC+1,sub_a+1 | |
| 1334 movff xC+0,sub_a+0 ; put result in sub_a:2 | |
| 1335 ; | |
| 1336 ; movff sub_a+1,gp_debug+1 | |
| 1337 ; movff sub_a+0,gp_debug+0 | |
| 1338 ; | |
| 1339 bra lt2942_get_accumulated_charge2 ; continue as with LT2942 | |
| 1340 | |
| 1341 | |
| 449 | 1342 lt2942_set_to_zero_percent: |
| 656 | 1343 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 |
| 1344 bra LTC2959_set_to_zero_percent | |
| 1345 | |
| 623 | 1346 movlw 0x02 ; point to accumulated charge registers |
| 634 | 1347 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
| 1348 movff battery_offset+1,SSP1BUF ; send battery offset, high byte | |
| 1349 rcall WaitMSSP ; wait for TX to complete | |
| 1350 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1351 movff battery_offset+0,SSP1BUF ; send battery offset, low byte | |
| 1352 rcall WaitMSSP ; wait for TX to complete | |
| 1353 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 656 | 1354 bra I2C_PEN ; stop condition (and return) |
| 1355 | |
| 1356 LTC2959_set_to_zero_percent: | |
| 1357 ; multiply battery_offset:2 with 159 and write result to LTC2959 | |
| 1358 | |
| 1359 MOVII battery_offset,xA | |
| 1360 MOVLI .159,xB ; 159,4745717 (0,085mAh/533nAh) | |
| 1361 call mult16x16 ; xC:4 = xA:2 * xB:2 | |
| 1362 | |
| 1363 movlw 0x03 ; point to accumulated charge registers | |
| 1364 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC | |
| 1365 movff xC+3,SSP1BUF ; send battery offset | |
| 643 | 1366 rcall WaitMSSP ; wait for TX to complete |
| 656 | 1367 rcall I2C_Check_ACK ; check for acknowledge by receiver |
| 1368 movff xC+2,SSP1BUF ; send battery offset | |
| 1369 rcall WaitMSSP ; wait for TX to complete | |
| 1370 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1371 movff xC+1,SSP1BUF ; send battery offset | |
| 1372 rcall WaitMSSP ; wait for TX to complete | |
| 1373 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1374 movff xC+0,SSP1BUF ; send battery offset | |
| 1375 rcall WaitMSSP ; wait for TX to complete | |
| 1376 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1377 bra I2C_PEN ; stop condition (and return) | |
| 1378 | |
| 628 | 1379 |
| 634 | 1380 ;----------------------------------------------------------------------------- |
| 1381 ; Read Gauge IC - Reset Accumulating Register to 0xFFFF | |
| 1382 ; | |
| 113 | 1383 global lt2942_charge_done |
| 634 | 1384 lt2942_charge_done: |
| 656 | 1385 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 |
| 1386 bra lt2959_charge_done | |
| 1387 | |
| 623 | 1388 movlw 0x02 ; point to accumulated charge registers |
| 634 | 1389 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
| 623 | 1390 setf SSP1BUF ; data byte |
| 634 | 1391 rcall WaitMSSP ; wait for TX to complete |
| 1392 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 623 | 1393 setf SSP1BUF ; data byte |
| 634 | 1394 rcall WaitMSSP ; wait for TX to complete |
| 1395 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 656 | 1396 bra I2C_PEN ; stop condition (and return) |
| 1397 | |
| 1398 lt2959_charge_done: | |
| 1399 ; Reset Accumulating Register to 0x009EFF61 (0xFFFF * .159) | |
| 1400 movlw 0x03 ; point to accumulated charge registers | |
| 1401 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC | |
| 1402 movlw 0x00 | |
| 1403 movwf SSP1BUF ; data byte | |
| 1404 rcall WaitMSSP ; wait for TX to complete | |
| 1405 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1406 movlw 0x9E | |
| 1407 movwf SSP1BUF ; data byte | |
| 643 | 1408 rcall WaitMSSP ; wait for TX to complete |
| 656 | 1409 rcall I2C_Check_ACK ; check for acknowledge by receiver |
| 1410 movlw 0xFF | |
| 1411 movwf SSP1BUF ; data byte | |
| 1412 rcall WaitMSSP ; wait for TX to complete | |
| 1413 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1414 movlw 0x61 | |
| 1415 movwf SSP1BUF ; data byte | |
| 1416 rcall WaitMSSP ; wait for TX to complete | |
| 1417 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
| 1418 bra I2C_PEN ; stop condition (and return) | |
| 634 | 1419 |
| 656 | 1420 |
| 634 | 1421 ;----------------------------------------------------------------------------- |
| 1422 ; Helper Function - send 1 Byte to the LT2942 Gauge IC | |
| 1423 ; | |
| 1424 I2C_TX_GAUGE: | |
| 1425 movwf i2c_temp2 ; save data byte to be sent | |
| 656 | 1426 rcall I2C_SEN ; start condition |
| 1427 movlw 0xC8 ; address byte + Write bit LT2942 | |
| 1428 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1429 movlw 0xC6 ; address byte + Write bit LTC2559 | |
| 1430 rcall I2C_TX ; send byte | |
| 634 | 1431 movf i2c_temp2,W ; restore data byte to be sent |
| 656 | 1432 bra I2C_TX ; send byte and return |
| 582 | 1433 |
| 634 | 1434 |
| 1435 ;----------------------------------------------------------------------------- | |
| 1436 ; Helper Function - receive 1 Byte from the LT2942 Gauge IC | |
| 1437 ; | |
| 113 | 1438 I2C_RX_GAUGE: |
| 656 | 1439 rcall I2C_RSEN ; repeated start condition |
| 1440 movlw 0xC9 ; address byte + Read bit LT2942 | |
| 1441 btfsc battery_gauge_type ; =1: Gauge IC LTC2959, =0: LT2942 | |
| 1442 movlw 0xC7 ; address byte + Read bit LTC2959 | |
| 1443 rcall I2C_TX ; send byte | |
| 1444 bra I2C_RCEN ; enable receive mode | |
| 634 | 1445 |
| 1446 | |
| 1447 ;----------------------------------------------------------------------------- | |
| 1448 ; Reset Hardware and Software Battery Gauge | |
| 1449 ; | |
| 1450 ; called from comm.asm and menu_tree.asm | |
| 1451 ; | |
| 1452 global reset_battery_gauge_and_lt2942 | |
| 1453 reset_battery_gauge_and_lt2942: | |
| 656 | 1454 btfsc battery_gauge_available ; battery gauge chip available? |
| 634 | 1455 call lt2942_charge_done ; YES - reset meter to 0xFFFF |
| 1456 ;bra reset_battery_gauge ; continue resetting gauge registers | |
| 582 | 1457 |
| 1458 | |
| 634 | 1459 ;----------------------------------------------------------------------------- |
| 1460 ; Reset Software Battery Gauge | |
| 1461 ; | |
| 631 | 1462 global reset_battery_gauge |
| 634 | 1463 reset_battery_gauge: |
| 1464 bsf block_battery_gauge ; suspend ISR from accessing the battery registers | |
| 1465 movlw .100 ; set battery level to 100% | |
| 1466 movwf batt_percent ; ... | |
| 1467 banksel battery_gauge ; select bank ISR data | |
| 1468 clrf battery_gauge+0 ; null the battery registers | |
| 1469 clrf battery_gauge+1 ; ... | |
| 1470 clrf battery_gauge+2 ; ... | |
| 1471 clrf battery_gauge+3 ; ... | |
| 1472 clrf battery_gauge+4 ; ... | |
| 1473 clrf battery_gauge+5 ; ... | |
| 654 | 1474 banksel charge_cycles |
| 1475 clrf charge_cycles+0 ; null the charge cycles | |
| 1476 clrf charge_cycles+1 ; ... | |
| 634 | 1477 banksel common ; back to bank common |
| 1478 goto eeprom_battery_gauge_write ; update battery registers in EEPROM, unblock ISR and return | |
| 631 | 1479 |
| 1480 | |
| 634 | 1481 |
| 604 | 1482 IFDEF _rx_functions |
| 1483 | |
| 634 | 1484 ;----------------------------------------------------------------------------- |
| 1485 ; OSTC TR - probe if TR Module available | |
| 1486 ; | |
| 560 | 1487 global I2C_probe_OSTC_rx |
| 1488 I2C_probe_OSTC_rx: | |
| 634 | 1489 bcf ostc_rx_present ; default to no TR module available |
| 623 | 1490 clrf WREG ; bank-safe set to zero of ... |
| 1491 movff WREG,rx_firmware_cur_major ; ... current TR module firmware, major | |
| 1492 movff WREG,rx_firmware_cur_minor ; ... current TR module firmware, minor | |
| 1493 movlw .5 ; max number of tries for detecting a TR module | |
| 634 | 1494 movwf hy ; initialize loop counter for tries |
| 604 | 1495 I2C_probe_OSTC_rx_1: |
| 656 | 1496 rcall I2C_SEN ; start condition |
| 623 | 1497 movlw 0x50 ; address byte + write bit |
| 656 | 1498 rcall I2C_TX ; send byte |
| 623 | 1499 bsf ostc_rx_present ; YES - TR module detected |
| 656 | 1500 rcall I2C_PEN ; stop condition |
| 623 | 1501 btfss ostc_rx_present ; was a TR module detected? |
| 1502 return ; NO - done | |
| 634 | 1503 |
| 1504 WAITMS .1 ; wait 1 ms | |
| 656 | 1505 rcall I2C_SEN ; start condition |
| 623 | 1506 movlw 0x50 ; address byte + write bit |
| 656 | 1507 rcall I2C_TX ; send byte |
| 634 | 1508 movlw 0x1B ; command: get firmware |
| 656 | 1509 rcall I2C_TX ; send byte |
| 1510 rcall I2C_PEN ; stop condition | |
| 634 | 1511 |
| 1512 WAITMS .1 ; wait 1 ms | |
| 1513 | |
| 656 | 1514 rcall I2C_SEN ; start condition |
| 623 | 1515 movlw 0x51 ; address byte + Read bit |
| 582 | 1516 movwf SSP1BUF ; control byte |
| 634 | 1517 rcall WaitMSSP ; wait for TX to complete |
| 656 | 1518 rcall I2C_RCEN ; enable receive mode |
| 623 | 1519 movff SSP1BUF,rx_firmware_cur_major ; store as firmware version, major |
| 656 | 1520 rcall I2C_ACKEN ; send master acknowledge |
| 582 | 1521 |
| 560 | 1522 ; last byte in read from RX circuity always with a NACK! |
| 656 | 1523 rcall I2C_RCEN ; enable receive mode |
| 623 | 1524 movff SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor |
| 650 | 1525 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 643 | 1526 |
| 623 | 1527 ; wait for TR module becoming ready |
| 634 | 1528 movff rx_firmware_cur_minor,i2c_temp1 ; copy minor firmware version to bank common |
| 623 | 1529 movlw .147 ; code for not ready, minor |
| 1530 cpfseq i2c_temp1 ; equal? | |
| 634 | 1531 return ; NO - TR module ready, done |
| 1532 movff rx_firmware_cur_major,i2c_temp1 ; YES - copy major firmware version to bank common | |
| 623 | 1533 movlw .27 ; - code for not ready, major |
| 1534 cpfseq i2c_temp1 ; - equal? | |
| 634 | 1535 return ; NO - TR module ready, done |
| 623 | 1536 bsf active_reset_ostc_rx ; YES - apply reset to TR module |
| 1537 WAITMS .5 ; - wait 5 ms | |
| 1538 bcf active_reset_ostc_rx ; - release reset | |
| 1539 WAITMS .250 ; - wait for 250 ms | |
| 1540 WAITMS .250 ; - wait another 250 ms | |
| 1541 decfsz hy,F ; - decrement counter for number of tries, became zero? | |
| 1542 bra I2C_probe_OSTC_rx_1 ; - NO - try again | |
| 1543 bcf ostc_rx_present ; - YES - something is wrong, flag TR module as not available | |
| 634 | 1544 return ; - done |
| 582 | 1545 |
| 560 | 1546 |
| 634 | 1547 ;----------------------------------------------------------------------------- |
| 1548 ; OSTC TR - get Tank Data | |
| 1549 ; | |
| 560 | 1550 global I2C_get_tankdata |
| 1551 I2C_get_tankdata: | |
| 656 | 1552 rcall I2C_SEN ; start condition |
| 623 | 1553 movlw 0x50 ; address byte + write bit |
| 656 | 1554 rcall I2C_TX ; send byte |
| 623 | 1555 movlw 0x1E ; read buffer2 (48 bytes) |
| 656 | 1556 rcall I2C_TX ; send byte |
| 1557 rcall I2C_PEN ; stop condition | |
| 634 | 1558 |
| 1559 WAITMS .1 ; wait 1 ms | |
| 1560 | |
| 560 | 1561 ; read 48 bytes |
| 656 | 1562 rcall I2C_SEN ; start condition |
| 623 | 1563 movlw 0x51 ; address byte + read bit |
| 656 | 1564 rcall I2C_TX ; send byte |
| 582 | 1565 movlw .47 ; 47 with ACK + 1 w/o ACK |
| 634 | 1566 movwf i2c_temp2 ; initialize loop counter |
| 1567 lfsr FSR2,rx_buffer ; point to start of rx data buffer | |
| 560 | 1568 I2C_get_tankdata_loop_read: |
| 656 | 1569 rcall I2C_RCEN ; enable receive mode |
| 634 | 1570 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer |
| 1571 bcf SSP1CON2,ACKDT ; reset ACKDT flag | |
| 656 | 1572 rcall I2C_ACKEN ; send master acknowledge |
| 634 | 1573 decfsz i2c_temp2,F ; decrement loop counter, done? |
| 1574 bra I2C_get_tankdata_loop_read ; NO - loop | |
| 1575 ; read last byte without ACK | |
| 656 | 1576 rcall I2C_RCEN ; enable receive mode |
| 634 | 1577 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer |
| 650 | 1578 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 643 | 1579 return ; done |
| 1580 | |
| 582 | 1581 |
| 1582 | |
| 634 | 1583 ;----------------------------------------------------------------------------- |
| 1584 ; OSTC TR - Firmware Update | |
| 1585 ; | |
| 628 | 1586 IFDEF _rx_update |
| 1587 | |
| 560 | 1588 global I2C_update_OSTC_rx |
| 623 | 1589 I2C_update_OSTC_rx: ; transfer 64 byte to RX co-processor |
| 1590 ; setup for write | |
| 582 | 1591 bcf i2c_error_flag ; clear error flag |
| 623 | 1592 lfsr FSR2,buffer ; initialize pointer to send buffer used for verify |
| 1593 movlw .64 ; initialize loop counter: 64 byte with ACK | |
| 1594 movwf i2c_temp2 ; ... | |
| 1595 ; address write | |
| 656 | 1596 rcall I2C_SEN ; start condition |
| 623 | 1597 movlw 0x50 ; address byte + write bit |
| 656 | 1598 rcall I2C_TX ; send byte |
| 623 | 1599 ; write 64 bytes |
| 1600 I2C_update_OSTC_loop: | |
| 1601 TBLRD*+ ; read a byte from program memory | |
| 1602 movff TABLAT,POSTINC2 ; copy to send buffer | |
| 656 | 1603 movf TABLAT,W ; copy to W |
| 1604 rcall I2C_TX ; send byte | |
| 623 | 1605 decfsz i2c_temp2,F ;decrement loop counter, became zero? |
| 1606 bra I2C_update_OSTC_loop ; NO - loop | |
| 656 | 1607 rcall I2C_PEN ; stop condition |
| 623 | 1608 WAITMS .1 ; - wait another 1 ms |
| 1609 ; setup for read-back | |
| 1610 lfsr FSR2,buffer ; reset pointer to begin of send buffer | |
| 1611 movlw .63 ; initialize loop counter: 63 byte with ACK + 1 w/o ACK | |
| 634 | 1612 movwf i2c_temp2 ; ... |
| 623 | 1613 ; address read-back |
| 656 | 1614 rcall I2C_SEN ; start condition |
| 623 | 1615 movlw 0x51 ; address byte + read bit |
| 656 | 1616 rcall I2C_TX ; send byte |
| 623 | 1617 ; read-back 64 bytes |
| 560 | 1618 I2C_update_OSTC_loop_read: |
| 656 | 1619 rcall I2C_RCEN ; enable receive mode |
| 634 | 1620 movf SSP1BUF,W ; copy received byte to WREG |
| 623 | 1621 cpfseq POSTINC2 ; compare read-back byte with sent byte, equal? |
| 1622 bsf i2c_error_flag ; NO - not equal, set error flag | |
| 634 | 1623 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
| 656 | 1624 rcall I2C_ACKEN ; send master acknowledge |
| 623 | 1625 decfsz i2c_temp2,F ; decrement loop counter, became zero? |
| 1626 bra I2C_update_OSTC_loop_read ; NO - loop | |
| 560 | 1627 ; 1 w/o ACK |
| 623 | 1628 bsf SSP1CON2, RCEN ; YES - enable receive mode |
| 634 | 1629 rcall WaitMSSP ; - wait for TX to complete |
| 623 | 1630 movf SSP1BUF,W ; - get 64th byte |
| 1631 cpfseq POSTINC2 ; - compare read-back byte with sent byte, equal? | |
| 1632 bsf i2c_error_flag ; NO - not equal, set error flag | |
| 650 | 1633 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 560 | 1634 WAITMS .1 |
| 623 | 1635 ; address commit |
| 656 | 1636 rcall I2C_SEN ; start condition |
| 623 | 1637 movlw 0x50 ; address byte + write bit |
| 656 | 1638 rcall I2C_TX ; send byte |
| 623 | 1639 movlw 0x1F ; write command |
| 656 | 1640 rcall I2C_TX ; send byte |
| 1641 rcall I2C_PEN ; stop condition | |
| 623 | 1642 WAITMS .5 ; required waiting time |
| 1643 ; error check | |
| 1644 btfss i2c_error_flag ; did an error occur? | |
| 1645 retlw .0 ; NO - data transfered successfully | |
| 1646 retlw .255 ; YES - error in data transfer occurred | |
| 582 | 1647 |
| 628 | 1648 ENDIF ; _rx_update |
| 1649 | |
| 1650 ENDIF ; _rx_functions | |
| 643 | 1651 |
| 634 | 1652 ;----------------------------------------------------------------------------- |
| 643 | 1653 ; Probe for MS5837 sensor |
| 1654 ; | |
| 1655 global I2C_probe_pressure_sensor ; Do not call from ISR! | |
| 1656 I2C_probe_pressure_sensor: ; Probe the type of sensor, set/clear press_sensor_type | |
| 1657 bcf press_sensor_type ; MS5541 as default | |
| 656 | 1658 rcall I2C_SEN ; start condition |
| 643 | 1659 movlw 0xEC ; address byte + write bit |
| 1660 movwf SSP1BUF ; control byte | |
| 1661 rcall WaitMSSP ; wait for TX to complete | |
| 656 | 1662 ; we need the ACKSTAT bit! Do not use I2C_TX routine here which might reset this bit! |
| 643 | 1663 btfss SSP1CON2,ACKSTAT ; ACK received? |
| 1664 bsf press_sensor_type ; MS5837 sensor found | |
| 656 | 1665 bra I2C_PEN ; stop condition |
| 643 | 1666 |
| 1667 ;-------------------------------------------------------------------- | |
| 1668 ; Helper Function - get the calibration parameter from # WREG address | |
| 1669 ; Do not call from ISR! | |
| 1670 I2C_get_calib_parameter: | |
| 1671 movwf lo ; store address | |
| 656 | 1672 rcall I2C_SEN ; start condition |
| 643 | 1673 movlw 0xEC ; address byte + write bit |
| 1674 rcall I2C_TX ; send byte | |
| 1675 movf lo,W ; Point to calibration register | |
| 1676 rcall I2C_TX ; send byte | |
| 656 | 1677 rcall I2C_PEN ; stop condition |
| 643 | 1678 |
| 656 | 1679 rcall I2C_SEN ; start condition |
| 643 | 1680 movlw 0xED ; address byte + read bit |
| 656 | 1681 rcall I2C_TX ; send byte |
| 1682 rcall I2C_RCEN ; enable receive mode | |
| 643 | 1683 movff SSP1BUF,dMSB ; High byte |
| 656 | 1684 rcall I2C_ACKEN ; send master acknowledge |
| 1685 | |
| 1686 rcall I2C_OneByteRX_NACK ; receive last byte with not acknowledge | |
| 643 | 1687 movff SSP1BUF,dLSB ; Low byte |
| 656 | 1688 bra I2C_PEN ; stop condition |
| 643 | 1689 |
| 1690 | |
| 1691 global I2C_get_calib_MS5837 ; Do not call from ISR! | |
| 1692 I2C_get_calib_MS5837: | |
| 1693 banksel common | |
| 1694 ; first, send a reset | |
| 656 | 1695 rcall I2C_SEN ; start condition |
| 643 | 1696 movlw 0xEC ; address byte + write bit |
| 1697 rcall I2C_TX ; send byte | |
| 1698 movlw 0x1E | |
| 1699 rcall I2C_TX ; send byte | |
| 656 | 1700 rcall I2C_PEN ; stop condition |
| 643 | 1701 WAITMS .5 ; 2.8ms according to datasheet |
| 1702 | |
| 1703 movlw 0xA2 ; Point to C1 | |
| 1704 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi | |
| 1705 movff dLSB,C1+0 ; store calib | |
| 1706 movff dMSB,C1+1 ; store calib | |
| 623 | 1707 |
| 643 | 1708 movlw 0xA4 ; Point to C2 |
| 1709 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi | |
| 1710 movff dLSB,C2+0 ; store calib | |
| 1711 movff dMSB,C2+1 ; store calib | |
| 1712 | |
| 1713 movlw 0xA6 ; Point to C3 | |
| 1714 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi | |
| 1715 movff dLSB,C3+0 ; store calib | |
| 1716 movff dMSB,C3+1 ; store calib | |
| 1717 | |
| 1718 movlw 0xA8 ; Point to C4 | |
| 1719 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi | |
| 1720 movff dLSB,C4+0 ; store calib | |
| 1721 movff dMSB,C4+1 ; store calib | |
| 1722 | |
| 1723 movlw 0xAA ; Point to C5 | |
| 1724 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi | |
| 1725 movff dLSB,C5+0 ; store calib | |
| 1726 movff dMSB,C5+1 ; store calib | |
| 1727 | |
| 1728 movlw 0xAC ; Point to C6 | |
| 1729 rcall I2C_get_calib_parameter ; returns calibration value in lo and hi | |
| 1730 movff dLSB,C6+0 ; store calib | |
| 1731 movff dMSB,C6+1 ; store calib | |
| 1732 | |
| 1733 return | |
| 1734 | |
| 1735 global I2C_get_press_val_MS5837 | |
| 1736 I2C_get_press_val_MS5837: | |
| 656 | 1737 btfsc i2c_reinit_sensor2 ; Sensor ok? |
| 1738 rcall I2CReset ; Try a I2C reset first | |
| 1739 btfsc i2c_reinit_sensor2 ; Sensor ok? | |
| 1740 bra I2C_get_press_val_MS5837_skip ; We did a reset, restart conversion first | |
| 1741 | |
| 1742 rcall I2C_SEN ; start condition | |
| 643 | 1743 movlw 0xEC ; address byte + write bit |
| 1744 rcall I2C_TX ; send byte | |
| 1745 movlw 0x00 ; command byte (0x00, read ADC) | |
| 1746 rcall I2C_TX ; send byte | |
| 1747 | |
| 656 | 1748 rcall I2C_RSEN ; repeated start condition |
| 643 | 1749 movlw 0xED ; address byte + read bit |
| 656 | 1750 rcall I2C_TX ; send byte |
| 643 | 1751 |
| 650 | 1752 bsf i2c_busy_pressure ; reading new pressure |
| 656 | 1753 rcall I2C_RCEN ; enable receive mode |
| 643 | 1754 movff SSP1BUF,D1_buffer+2 ; Upper byte |
| 656 | 1755 rcall I2C_ACKEN ; send master acknowledge |
| 1756 rcall I2C_RCEN ; enable receive mode | |
| 643 | 1757 movff SSP1BUF,D1_buffer+1 ; high byte |
| 656 | 1758 rcall I2C_ACKEN ; send master acknowledge |
| 1759 rcall I2C_RCEN ; enable receive mode | |
| 643 | 1760 movff SSP1BUF,D1_buffer+0 ; Low byte |
| 1761 | |
| 650 | 1762 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 1763 bcf i2c_busy_pressure ; reading new pressure done. | |
| 656 | 1764 |
| 1765 I2C_get_press_val_MS5837_skip: | |
| 643 | 1766 ; Start temperature measurement |
| 656 | 1767 rcall I2C_SEN ; start condition |
| 643 | 1768 movlw 0xEC ; address byte + write bit |
| 1769 rcall I2C_TX ; send byte | |
| 1770 movlw 0x58 ; OSR=4096, type=D2 | |
| 1771 rcall I2C_TX ; send byte | |
| 656 | 1772 rcall I2C_PEN ; stop condition |
| 643 | 1773 bcf ms5837_state ; =0: result of temperature will be in the ADC |
| 656 | 1774 bcf i2c_reinit_sensor2 ; Clear error flag |
| 643 | 1775 return |
| 1776 | |
| 1777 global I2C_get_temp_val_MS5837 | |
| 1778 I2C_get_temp_val_MS5837: | |
| 656 | 1779 btfsc i2c_reinit_sensor2 ; Sensor ok? |
| 1780 rcall I2CReset ; Try a I2C reset first | |
| 1781 btfsc i2c_reinit_sensor2 ; Sensor ok? | |
| 1782 bra I2C_get_temp_val_MS5837_skip ; We did a reset, restart conversion first | |
| 1783 | |
| 1784 rcall I2C_SEN ; start condition | |
| 643 | 1785 movlw 0xEC ; address byte + write bit |
| 1786 rcall I2C_TX ; send byte | |
| 1787 movlw 0x00 ; command byte (0x00, read ADC) | |
| 1788 rcall I2C_TX ; send byte | |
| 1789 | |
| 656 | 1790 rcall I2C_RSEN ; repeated start condition |
| 643 | 1791 movlw 0xED ; address byte + read bit |
| 656 | 1792 rcall I2C_TX ; send byte |
| 643 | 1793 |
| 650 | 1794 bsf i2c_busy_temperature ; reading new temperature |
| 656 | 1795 rcall I2C_RCEN ; enable receive mode |
| 643 | 1796 movff SSP1BUF,D2_buffer+2 ; Upper byte |
| 656 | 1797 rcall I2C_ACKEN ; send master acknowledge |
| 1798 rcall I2C_RCEN ; enable receive mode | |
| 643 | 1799 movff SSP1BUF,D2_buffer+1 ; high byte |
| 656 | 1800 rcall I2C_ACKEN ; send master acknowledge |
| 1801 rcall I2C_RCEN ; enable receive mode | |
| 643 | 1802 movff SSP1BUF,D2_buffer+0 ; Low byte |
| 1803 | |
| 650 | 1804 rcall I2C_MasterNotAckStop ; Master NOT acknowledge and Stop |
| 1805 bcf i2c_busy_temperature ; reading new temperature done. | |
| 656 | 1806 |
| 1807 I2C_get_temp_val_MS5837_skip: | |
| 643 | 1808 ; Start pressure measurement |
| 656 | 1809 rcall I2C_SEN ; start condition |
| 643 | 1810 movlw 0xEC ; address byte + write bit |
| 1811 rcall I2C_TX ; send byte | |
| 1812 movlw 0x48 ; OSR=4096, type=D1 | |
| 1813 rcall I2C_TX ; send byte | |
| 656 | 1814 rcall I2C_PEN ; stop condition |
| 643 | 1815 bsf ms5837_state ; =0: result of pressure will be in the ADC |
| 656 | 1816 bcf i2c_reinit_sensor2 ; Clear error flag |
| 643 | 1817 return |
| 1818 | |
| 1819 | |
| 1820 ;----------------------------------------------------------------------------- | |
| 1821 ; I2C Bus error checker | |
| 1822 ; | |
| 1823 global check_i2c_error | |
| 1824 extern TFT_message_i2c_error | |
| 1825 check_i2c_error: | |
| 1826 btfss i2c_error_flag | |
| 1827 return | |
| 656 | 1828 bcf i2c_error_flag_lock ; arm error vault again |
| 643 | 1829 incf message_counter,F ; increase message counter |
| 1830 goto TFT_message_i2c_error ; show message for battery low (battery percent) and return | |
| 1831 | |
| 1832 ;----------------------------------------------------------------------------- | |
| 582 | 1833 END |
