Mercurial > public > hwos_code
annotate src/i2c.asm @ 642:a9a0188091e4
fix rare upgrade issue with OSTC sport 2019 hardware
author | heinrichsweikamp |
---|---|
date | Thu, 14 Jan 2021 16:24:07 +0100 |
parents | 8c1f1f334275 |
children | 7d8a4c60ec1a 5b7fe7777425 |
rev | line source |
---|---|
0 | 1 ;============================================================================= |
2 ; | |
634 | 3 ; File i2c.asm * combined next generation V3.09.4b |
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" |
631 | 51 #include "eeprom_rs232.inc" |
113 | 52 |
582 | 53 |
634 | 54 ;============================================================================= |
55 i2c CODE | |
582 | 56 ;============================================================================= |
0 | 57 |
634 | 58 |
59 ;----------------------------------------------------------------------------- | |
60 ; Helper Function - send 1 Byte, wait for end of transmission and check ackn | |
61 ; | |
0 | 62 I2C_TX: |
634 | 63 movwf SSP1BUF ; put byte to be sent into TX buffer |
64 rcall WaitMSSP ; wait for TX to complete | |
65 bra I2C_Check_ACK ; check for acknowledge by receiver and return | |
66 | |
0 | 67 |
634 | 68 ;----------------------------------------------------------------------------- |
69 ; Helper Function - get two Bytes and divide hi:lo/16 (signed) | |
70 ; | |
71 I2C_TwoBytesRX_div16: | |
72 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
73 movff SSP1BUF,hi ; copy data byte to hi | |
74 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
75 movff SSP1BUF,lo ; copy data byte to lo | |
76 I2C_TwoBytesRX_div16_2: ; divide hi:lo/16 (signed) only | |
582 | 77 bcf STATUS,C |
604 | 78 btfsc hi,7 ; copy sign bit to carry |
582 | 79 bsf STATUS,C |
80 rrcf hi ; /2 | |
81 rrcf lo | |
634 | 82 ;bra I2C_TwoBytesRX_div8 ; continue dividing hi:lo/8 (signed) |
83 | |
84 | |
85 ;----------------------------------------------------------------------------- | |
86 ; Helper Function - divide hi:lo/8 (signed) | |
87 ; | |
88 I2C_TwoBytesRX_div8: | |
582 | 89 bcf STATUS,C |
604 | 90 btfsc hi,7 ; copy sign bit to carry |
582 | 91 bsf STATUS,C |
92 rrcf hi ; /4 | |
93 rrcf lo | |
94 bcf STATUS,C | |
604 | 95 btfsc hi,7 ; copy sign bit to carry |
582 | 96 bsf STATUS,C |
97 rrcf hi ; /8 | |
98 rrcf lo | |
99 bcf STATUS,C | |
604 | 100 btfsc hi,7 ; copy sign bit to carry |
582 | 101 bsf STATUS,C |
102 rrcf hi ; /16 | |
103 rrcf lo | |
634 | 104 return ; done |
105 | |
0 | 106 |
634 | 107 ;----------------------------------------------------------------------------- |
108 ; Read Accelerometer | |
109 ; | |
582 | 110 global I2C_RX_accelerometer |
0 | 111 I2C_RX_accelerometer: |
628 | 112 btfsc compass_type3 ; compass3 ? |
113 bra I2C_RX_accelerometer_compass3 ; YES | |
604 | 114 btfsc compass_type2 ; compass2 ? |
115 bra I2C_RX_accelerometer_compass2 ; YES | |
628 | 116 btfsc compass_type1 ; compass1 ? |
604 | 117 bra I2C_RX_accelerometer_compass1 ; YES |
628 | 118 ;bra I2C_RX_accelerometer_compass0 ; NO - compass0 then |
119 | |
560 | 120 I2C_RX_accelerometer_compass0: |
604 | 121 bsf SSP1CON2,SEN ; start condition |
634 | 122 rcall WaitMSSP ; wait for TX to complete |
582 | 123 movlw 0x38 ; address |
634 | 124 rcall I2C_TX ; send byte |
125 movlw 0x00 ; ?? | |
126 rcall I2C_TX ; send byte | |
604 | 127 bsf SSP1CON2,RSEN ; repeated start condition |
634 | 128 rcall WaitMSSP ; wait for TX to complete |
582 | 129 movlw 0x39 ; address |
634 | 130 rcall I2C_TX ; send byte |
131 rcall I2C_OneByteRX ; get status byte | |
132 movf SSP1BUF,W ; copy status byte to WREG | |
158 | 133 |
582 | 134 ; Non-flipped screen: |
135 ; Chip orientation on the PCB requires | |
604 | 136 ; Original = corrected |
582 | 137 ; x = -x |
138 ; y = -y | |
139 ; z = -z | |
0 | 140 |
582 | 141 ; Flipped screen: |
142 ; Chip orientation on the PCB requires | |
604 | 143 ; Original = corrected |
582 | 144 ; x = x |
145 ; y = y | |
146 ; z = -z | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
147 |
604 | 148 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
623 | 149 btfsc flip_screen ; 180° rotation? |
604 | 150 bra I2C_RX_accelerometer2 ; YES |
634 | 151 comf hi ; NO - 16 bit sign change |
152 negf lo ; - .... | |
153 btfsc STATUS,C ; - carry to propagate? | |
154 incf hi,F ; - YES - do it | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
155 I2C_RX_accelerometer2: |
634 | 156 MOVII mpr,accel_DX ; copy result to accel_DX |
157 | |
623 | 158 rcall I2C_TwoBytesRX_div16 ; get two bytes and divide /16 (signed) |
159 btfsc flip_screen ; 180° rotation? | |
160 bra I2C_RX_accelerometer3 ; YES | |
634 | 161 comf hi ; NO - 16 bit sign change |
162 negf lo ; - ... | |
163 btfsc STATUS,C ; - carry to propagate? | |
164 incf hi,F ; YES - do it | |
165 I2C_RX_accelerometer3: | |
166 MOVII mpr,accel_DY ; copy result to accel_DY | |
167 | |
168 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
169 movff SSP1BUF,hi ; copy data byte to hi | |
170 bsf SSP1CON2,RCEN ; enable receive mode | |
171 rcall WaitMSSP ; wait for TX to complete | |
172 ; according to data sheet there should be no master acknowledge for the last byte (accel_DZ+0)... | |
173 movff SSP1BUF,lo ; copy data byte to lo | |
174 rcall I2C_TwoBytesRX_div16_2 ; divide hi:lo/16 (signed) | |
623 | 175 comf hi ; 16 bit sign change |
634 | 176 negf lo ; ... |
623 | 177 btfsc STATUS,C ; carry to propagate? |
178 incf hi,F ; YES - do it | |
634 | 179 MOVII mpr,accel_DZ ; copy result to accel_DZ |
180 bsf SSP1CON2,PEN ; stop condition | |
181 bra WaitMSSP ; wait for TX to complete and return | |
0 | 182 |
183 | |
427 | 184 I2C_RX_accelerometer_compass1: |
623 | 185 bsf SSP1CON2,SEN ; start condition |
634 | 186 rcall WaitMSSP ; wait for TX to complete |
582 | 187 movlw 0x3C ; address |
634 | 188 rcall I2C_TX ; send byte |
582 | 189 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) |
634 | 190 rcall I2C_TX ; send byte |
623 | 191 bsf SSP1CON2,RSEN ; repeated start condition (!) |
634 | 192 rcall WaitMSSP ; wait for TX to complete |
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 |
634 | 258 bsf SSP1CON2,RCEN ; enable receive mode |
259 rcall WaitMSSP ; wait for TX to complete | |
260 ; according to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)... | |
623 | 261 movff SSP1BUF,hi ; accel_DZ+1 |
262 bsf SSP1CON2,PEN ; stop condition | |
634 | 263 rcall WaitMSSP ; wait for TX to complete |
582 | 264 rcall I2C_TwoBytesRX_div16_2 ; divide lo:hi/16 (signed) only |
623 | 265 comf hi ; 16 bit sign change for Z |
634 | 266 negf lo ; ... |
623 | 267 btfsc STATUS,C ; carry to propagate? |
268 incf hi,F ; YES - do it | |
269 MOVII mpr,accel_DZ ; copy result | |
634 | 270 return ; done |
271 | |
582 | 272 |
560 | 273 I2C_RX_accelerometer_compass2: |
623 | 274 bsf SSP1CON2,SEN ; start condition |
634 | 275 rcall WaitMSSP ; wait for TX to complete |
582 | 276 movlw 0x32 ; address |
634 | 277 rcall I2C_TX ; send byte |
582 | 278 movlw b'10101000' ; 0x28 with auto-increment (MSB=1) |
634 | 279 rcall I2C_TX ; send byte |
623 | 280 bsf SSP1CON2,RSEN ; repeated start condition (!) |
634 | 281 rcall WaitMSSP ; wait for TX to complete |
582 | 282 movlw 0x33 ; address |
634 | 283 bra I2C_RX_accelerometer_common ; continue with common part |
624 | 284 |
285 I2C_RX_accelerometer_compass3: | |
634 | 286 bsf SSP1CON2,SEN ; start condition |
287 rcall WaitMSSP ; wait for TX to complete | |
628 | 288 movlw 0x3A ; address |
634 | 289 rcall I2C_TX ; send byte |
628 | 290 movlw 0x28 ; 0x28 (OUT_X_L_A) |
634 | 291 rcall I2C_TX ; send byte |
628 | 292 bsf SSP1CON2,RSEN ; repeated start condition (!) |
634 | 293 rcall WaitMSSP ; wait for TX to complete |
628 | 294 movlw 0x3B ; address |
634 | 295 bra I2C_RX_accelerometer_common ; continue with common part |
623 | 296 |
297 | |
298 ;----------------------------------------------------------------------------- | |
634 | 299 ; Helper Function - receive 1 Byte with Acknowledge |
300 ; | |
301 I2C_OneByteRX: | |
302 bsf SSP1CON2,RCEN ; enable receive mode | |
303 rcall WaitMSSP ; wait for TX to complete | |
304 bsf SSP1CON2,ACKEN ; send master acknowledge | |
305 bra WaitMSSP ; wait for TX to complete and return | |
306 | |
307 | |
308 ;----------------------------------------------------------------------------- | |
309 ; Read Compass | |
310 ; | |
623 | 311 IFDEF _compass |
0 | 312 |
582 | 313 global I2C_RX_compass |
0 | 314 I2C_RX_compass: |
628 | 315 btfsc compass_type3 ; compass 3 ? |
316 bra I2C_RX_compass3 ; YES | |
317 btfsc compass_type2 ; compass 2 ? | |
623 | 318 bra I2C_RX_compass2 ; YES |
628 | 319 btfsc compass_type1 ; compass 1 ? |
623 | 320 bra I2C_RX_compass1 ; YES |
628 | 321 ;bra I2C_RX_compass0 ; NO - compass 0 then |
322 | |
560 | 323 I2C_RX_compass0: |
623 | 324 bsf SSP1CON2,SEN ; start condition |
634 | 325 rcall WaitMSSP ; wait for TX to complete |
582 | 326 movlw 0x3C ; address |
634 | 327 rcall I2C_TX ; send byte |
328 movlw 0x03 ; ?? | |
329 rcall I2C_TX ; send byte | |
623 | 330 bsf SSP1CON2,PEN ; stop condition |
634 | 331 rcall WaitMSSP ; wait for TX to complete |
623 | 332 bsf SSP1CON2,SEN ; start condition |
634 | 333 rcall WaitMSSP ; wait for TX to complete |
582 | 334 movlw 0x3D ; address |
634 | 335 rcall I2C_TX ; send byte |
0 | 336 |
582 | 337 ; Compass IC sends data in following order: |
338 ; x MSB | |
339 ; x LSB | |
340 ; z MSB | |
341 ; z LSB | |
342 ; y MSB | |
343 ; y LSB | |
0 | 344 |
582 | 345 ; Non-flipped screen |
346 ; Chip orientation on the PCB requires | |
347 ; Original = Corrected | |
348 ; x = -y | |
349 ; z = z | |
350 ; y = x | |
0 | 351 |
582 | 352 ; Flipped screen |
353 ; Chip orientation on the PCB requires | |
354 ; Original = Corrected | |
355 ; x = y | |
356 ; z = z | |
357 ; y = -x | |
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
358 |
634 | 359 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 360 movff SSP1BUF,compass_DY+1 ; data byte |
634 | 361 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 362 movff SSP1BUF,compass_DY+0 ; data byte |
363 btfsc flip_screen ; 180° rotation? | |
364 bra I2C_RX_compass0_2 ; NO | |
365 banksel compass_DY ; YES - flip Y | |
366 comf compass_DY+1 ; - 16 bit sign change | |
582 | 367 negf compass_DY+0 |
623 | 368 btfsc STATUS,C ; - carry to propagate? |
369 incf compass_DY+1,F ; YES - do it | |
582 | 370 banksel common |
623 | 371 I2C_RX_compass0_2: |
634 | 372 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 373 movff SSP1BUF,compass_DZ+1 ; data byte |
634 | 374 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 375 movff SSP1BUF,compass_DZ+0 ; data byte |
634 | 376 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 377 movff SSP1BUF,compass_DX+1 ; data byte |
628 | 378 bsf SSP1CON2,RCEN ; enable receive mode |
634 | 379 rcall WaitMSSP ; wait for TX to complete |
623 | 380 movff SSP1BUF,compass_DX+0 ; data byte |
381 bsf SSP1CON2,PEN ; stop condition | |
634 | 382 rcall WaitMSSP ; wait for TX to complete |
623 | 383 btfss flip_screen ; 180° rotation? |
384 return ; NO - done | |
385 banksel compass_DX ; YES - flip X | |
386 comf compass_DX+1 ; - 16 bit sign change | |
582 | 387 negf compass_DX+0 |
623 | 388 btfsc STATUS,C ; - carry to propagate? |
389 incf compass_DX+1,F ; YES - do it | |
634 | 390 banksel common ; back to bank common |
391 return ; done | |
392 | |
582 | 393 |
628 | 394 I2C_RX_compass1: ; compass type 1 |
623 | 395 bsf SSP1CON2,SEN ; start condition |
634 | 396 rcall WaitMSSP ; wait for TX to complete |
582 | 397 movlw 0x3C ; address |
634 | 398 rcall I2C_TX ; send byte |
582 | 399 movlw b'10001000' ; 0x08 with auto-increment (MSB=1) |
634 | 400 rcall I2C_TX ; send byte |
623 | 401 bsf SSP1CON2,RSEN ; repeated start condition (!) |
634 | 402 rcall WaitMSSP ; wait for TX to complete |
582 | 403 movlw 0x3D ; address |
634 | 404 rcall I2C_TX ; send byte |
623 | 405 ;rcall WaitMSSP ; TODO needed? (mH) |
634 | 406 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 407 movff SSP1BUF,lo ; data byte |
634 | 408 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 409 movff SSP1BUF,hi ; data byte |
634 | 410 rcall I2C_TwoBytesRX_div8 ; divide hi,lo by 8 (signed) |
411 MOVII mpr,compass_DX ; copy result | |
623 | 412 btfss flip_screen ; 180° rotation? |
413 bra I2C_RX_compass1_1 ; NO | |
414 banksel compass_DX ; YES - flip X | |
415 comf compass_DX+1 ; - 16 bit sign change | |
582 | 416 negf compass_DX+0 |
623 | 417 btfsc STATUS,C ; - carry to propagate? |
418 incf compass_DX+1,F ; YES - do it | |
582 | 419 banksel common |
427 | 420 I2C_RX_compass1_1: |
634 | 421 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 422 movff SSP1BUF,lo ; data byte |
634 | 423 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 424 movff SSP1BUF,hi ; data byte |
634 | 425 rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
623 | 426 MOVII mpr,compass_DY |
427 btfss flip_screen ; 180° rotation? | |
428 bra I2C_RX_compass1_2 ; NO | |
429 banksel compass_DY ; YES - flip Y | |
430 comf compass_DY+1 ; - 16 bit sign change | |
634 | 431 negf compass_DY+0 ; - ... |
623 | 432 btfsc STATUS,C ; - carry to propagate? |
433 incf compass_DY+1,F ; YES - do it | |
434 banksel common | |
427 | 435 I2C_RX_compass1_2: |
634 | 436 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 437 movff SSP1BUF,lo ; data byte |
582 | 438 bsf SSP1CON2, RCEN ; Enable receive mode |
634 | 439 rcall WaitMSSP ; wait for TX to complete |
623 | 440 movff SSP1BUF,hi ; data byte |
634 | 441 rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
442 MOVII mpr,compass_DZ ; copy result | |
623 | 443 bsf SSP1CON2,PEN ; stop condition |
444 bra WaitMSSP ; ... and return | |
560 | 445 |
634 | 446 |
628 | 447 I2C_RX_compass2: ; compass type 2 |
623 | 448 bsf SSP1CON2,SEN ; start condition |
634 | 449 rcall WaitMSSP ; wait for TX to complete |
582 | 450 movlw 0x3C ; address |
634 | 451 rcall I2C_TX ; send byte |
582 | 452 movlw 0xE8 ; 0x68 with auto-increment (MSB=1) |
634 | 453 rcall I2C_TX ; send byte |
623 | 454 bsf SSP1CON2,RSEN ; repeated start condition (!) |
634 | 455 rcall WaitMSSP ; wait for TX to complete |
582 | 456 movlw 0x3D ; address |
634 | 457 rcall I2C_TX ; send byte |
628 | 458 I2C_RX_compass2_xx: ; compass 3 joins in here |
634 | 459 ; rcall WaitMSSP ; wait for TX to complete (not needed, as included in I2C_TX) |
460 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
623 | 461 movff SSP1BUF,lo ; data byte |
634 | 462 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 463 movff SSP1BUF,hi ; data byte |
634 | 464 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
623 | 465 btfsc flip_screen ; 180° rotation? |
466 bra I2C_RX_compass2_1 ; YES - do nothing with X | |
467 ; NO - flip X | |
468 comf hi ; - 16 bit sign change | |
634 | 469 negf lo ; - ... |
623 | 470 btfsc STATUS,C ; - carry to propagate? |
471 incf hi,F ; YES - do it | |
582 | 472 I2C_RX_compass2_1: |
623 | 473 MOVII mpr,compass_DX |
634 | 474 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 475 movff SSP1BUF,lo ; data byte |
634 | 476 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 477 movff SSP1BUF,hi ; data byte |
634 | 478 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
623 | 479 btfss flip_screen ; 180° rotation? |
480 bra I2C_RX_compass2_2 ; NO - do nothing with Y | |
481 ; YES - flip Y | |
482 comf hi ; - 16 bit sign change | |
634 | 483 negf lo ; - ... |
623 | 484 btfsc STATUS,C ; - carry to propagate? |
485 incf hi,F ; YES - do it | |
486 I2C_RX_compass2_2: | |
487 MOVII mpr,compass_DY | |
634 | 488 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 489 movff SSP1BUF,lo ; data byte |
634 | 490 rcall I2C_OneByteRX ; receive 1 byte with acknowledge |
623 | 491 movff SSP1BUF,hi ; data byte |
634 | 492 ; rcall I2C_TwoBytesRX_div8 ; divide hi, lo by 8 (signed) |
493 MOVII mpr,compass_DZ ; copy result | |
623 | 494 bsf SSP1CON2,PEN ; stop condition |
628 | 495 bra WaitMSSP ; ...and return |
582 | 496 |
634 | 497 |
628 | 498 I2C_RX_compass3: ; compass type 3 |
499 bsf SSP1CON2,SEN ; start condition | |
634 | 500 rcall WaitMSSP ; wait for TX to complete |
628 | 501 movlw 0x3C ; address |
634 | 502 rcall I2C_TX ; send byte |
628 | 503 movlw 0xA8 ; 0x28 with auto-increment (MSB=1) |
634 | 504 rcall I2C_TX ; send byte |
628 | 505 bsf SSP1CON2,RSEN ; repeated start condition (!) |
634 | 506 rcall WaitMSSP ; wait for TX to complete |
628 | 507 movlw 0x3D ; address |
634 | 508 rcall I2C_TX ; send byte |
628 | 509 bra I2C_RX_compass2_xx ; join with compass 2 code |
624 | 510 |
623 | 511 ENDIF ; _compass |
512 | |
634 | 513 |
623 | 514 ;----------------------------------------------------------------------------- |
634 | 515 ; Initialize Compass / Accelerometer Chip |
516 ; | |
582 | 517 global I2C_init_compass |
0 | 518 I2C_init_compass: |
634 | 519 bsf compass_enabled ; flag compass will be enabled |
520 bcf compass_type2 ; clear in preparation of chip detection | |
521 bcf compass_type3 ; ... | |
623 | 522 |
628 | 523 ; probe for compass 3 |
623 | 524 bsf SSP1CON2,SEN ; start condition |
634 | 525 rcall WaitMSSP ; wait for TX to complete |
628 | 526 movlw 0x3A ; address byte + write bit |
582 | 527 movwf SSP1BUF ; control byte |
634 | 528 rcall WaitMSSP ; wait for TX to complete |
529 btfss SSP1CON2,ACKSTAT ; ACK received? | |
530 bsf compass_type3 ; YES - ACK was send, compass 3 found | |
628 | 531 bsf SSP1CON2,PEN ; stop condition |
634 | 532 rcall WaitMSSP ; wait for TX to complete |
628 | 533 |
534 btfsc compass_type3 ; compass 3 found? | |
535 bra I2C_init_compass3 ; YES - initialize compass 3 | |
536 | |
537 ; probe for compass 2 | |
538 bsf SSP1CON2,SEN ; start condition | |
634 | 539 rcall WaitMSSP ; wait for TX to complete |
628 | 540 movlw 0x32 ; address byte + write bit |
541 movwf SSP1BUF ; control byte | |
634 | 542 rcall WaitMSSP ; wait for TX to complete |
543 btfss SSP1CON2,ACKSTAT ; ACK received? | |
544 bsf compass_type2 ; YES - ACK send, compass 2 found | |
628 | 545 bsf SSP1CON2,PEN ; stop condition |
634 | 546 rcall WaitMSSP ; wait for TX to complete |
623 | 547 |
628 | 548 btfsc compass_type2 ; compass 2 found? |
549 bra I2C_init_compass2 ; YES - initialize compass 2 | |
550 | |
551 ; probe for compass 0 or 1 | |
634 | 552 bsf compass_type1 ; assume compass 1 by default |
623 | 553 bsf SSP1CON2,SEN ; start condition |
634 | 554 rcall WaitMSSP ; wait for TX to complete |
582 | 555 movlw 0x3C ; address |
634 | 556 rcall I2C_TX ; send byte |
557 movlw 0x0F ; ?? | |
558 rcall I2C_TX ; send byte | |
623 | 559 bsf SSP1CON2,PEN ; stop condition |
634 | 560 rcall WaitMSSP ; wait for TX to complete |
623 | 561 bsf SSP1CON2,SEN ; start condition |
634 | 562 rcall WaitMSSP ; wait for TX to complete |
582 | 563 movlw 0x3D ; address |
634 | 564 rcall I2C_TX ; send byte |
565 rcall I2C_OneByteRX ; receive 1 byte with acknowledge | |
628 | 566 movlw 0x49 ; 0x49 = compass 1 |
634 | 567 cpfseq SSP1BUF ; 0x49 received? |
568 bcf compass_type1 ; NO - clear flag for compass 1 | |
623 | 569 bsf SSP1CON2,PEN ; stop condition |
634 | 570 rcall WaitMSSP ; wait for TX to complete |
582 | 571 |
628 | 572 btfsc compass_type1 ; compass 1 found? |
573 bra I2C_init_compass1 ; YES - initialize compass 1 | |
574 ;bra I2C_init_compass0 ; NO - must be compass 0 then | |
575 | |
634 | 576 |
628 | 577 I2C_init_compass0: |
578 ; magnetic | |
623 | 579 bsf SSP1CON2,SEN ; start condition |
634 | 580 rcall WaitMSSP ; wait for TX to complete |
582 | 581 movlw 0x3C ; address |
634 | 582 rcall I2C_TX ; send byte |
583 movlw 0x00 ; ?? | |
584 rcall I2C_TX ; send byte | |
623 | 585 movlw b'01101000' ; ConfigA: 3 Hz, 8 samples averaged |
634 | 586 rcall I2C_TX ; send byte |
623 | 587 movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) |
634 | 588 swapf i2c_temp1,F ; |
589 comf i2c_temp1,F ; | |
590 bcf STATUS,C ; | |
591 rlcf i2c_temp1 ; | |
592 movf i2c_temp1,W ; | |
593 rcall I2C_TX ; send byte | |
594 movlw b'00000000' ; select continuous mode | |
595 rcall I2C_TX ; send byte | |
623 | 596 bsf SSP1CON2,PEN ; stop condition |
634 | 597 rcall WaitMSSP ; wait for TX to complete |
598 | |
628 | 599 ; accelerometer |
631 | 600 rcall I2C_sleep_accelerometer0 ; registers can only be changed in standby mode |
628 | 601 |
602 bsf SSP1CON2,SEN ; start condition | |
634 | 603 rcall WaitMSSP ; wait for TX to complete |
628 | 604 movlw 0x38 ; address |
634 | 605 rcall I2C_TX ; send byte |
628 | 606 movlw 0x0E ; XYZ_DATA_CFG |
634 | 607 rcall I2C_TX ; send byte |
628 | 608 movlw b'00000000' ; high pass filter = 0, +/- 2 g range |
634 | 609 rcall I2C_TX ; send byte |
628 | 610 bsf SSP1CON2,PEN ; stop condition |
634 | 611 rcall WaitMSSP ; wait for TX to complete |
628 | 612 bsf SSP1CON2,SEN ; start condition |
634 | 613 rcall WaitMSSP ; wait for TX to complete |
628 | 614 movlw 0x38 ; address |
634 | 615 rcall I2C_TX ; send byte |
628 | 616 movlw 0x2A ; CTRL_REG1 |
634 | 617 rcall I2C_TX ; send byte |
628 | 618 ; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode |
619 movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode | |
634 | 620 rcall I2C_TX ; send byte |
628 | 621 movlw b'00000010' ; CTRL_REG2: high-res in active mode |
634 | 622 rcall I2C_TX ; send byte |
628 | 623 bsf SSP1CON2,PEN ; stop condition |
634 | 624 rcall WaitMSSP ; wait for TX to complete |
628 | 625 |
626 bsf SSP1CON2,SEN ; start condition | |
634 | 627 rcall WaitMSSP ; wait for TX to complete |
628 | 628 movlw 0x38 ; address |
634 | 629 rcall I2C_TX ; send byte |
628 | 630 movlw 0x2A ; CTRL_REG1 |
634 | 631 rcall I2C_TX ; send byte |
628 | 632 ; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode |
633 movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode | |
634 | 634 rcall I2C_TX ; send byte |
628 | 635 bsf SSP1CON2,PEN ; stop condition |
634 | 636 bra WaitMSSP ; wait for TX to complete and return |
0 | 637 |
628 | 638 |
427 | 639 I2C_init_compass1: |
623 | 640 bsf SSP1CON2,SEN ; start condition |
634 | 641 rcall WaitMSSP ; wait for TX to complete |
582 | 642 movlw 0x3C ; address |
634 | 643 rcall I2C_TX ; send byte |
582 | 644 movlw 0x9F ; 1F with auto-increment (MSB=1) |
634 | 645 rcall I2C_TX ; send byte |
582 | 646 movlw b'00000000' ; CTRL0 |
634 | 647 rcall I2C_TX ; send byte |
623 | 648 movlw b'00101111' ; CTRL1 (6.25 Hz, BDU=0, x,y,z = ON) |
634 | 649 rcall I2C_TX ; send byte |
623 | 650 movlw b'11000000' ; CTRL2 (50 Hz, +/- 2g) |
634 | 651 rcall I2C_TX ; send byte |
582 | 652 movlw b'00000000' ; CTRL3 |
634 | 653 rcall I2C_TX ; send byte |
582 | 654 movlw b'00000000' ; CTRL4 |
634 | 655 rcall I2C_TX ; send byte |
623 | 656 movlw b'01100100' ; CTRL5 HIGH res, 6.25 Hz |
634 | 657 rcall I2C_TX ; send byte |
623 | 658 movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) |
659 movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) | |
582 | 660 dcfsnz i2c_temp1,F ; = 1? |
623 | 661 movlw b'01100000' ; YES - CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) |
582 | 662 dcfsnz i2c_temp1,F ; = 2? |
623 | 663 movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) |
582 | 664 dcfsnz i2c_temp1,F ; = 3? |
623 | 665 movlw b'01000000' ; YES - CTRL6 (+/-8 Gauss) |
582 | 666 dcfsnz i2c_temp1,F ; = 4? |
623 | 667 movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) |
582 | 668 dcfsnz i2c_temp1,F ; = 5? |
623 | 669 movlw b'00100000' ; YES - CTRL6 (+/-4 Gauss) |
582 | 670 dcfsnz i2c_temp1,F ; = 6? |
623 | 671 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) |
582 | 672 dcfsnz i2c_temp1,F ; = 7? |
623 | 673 movlw b'00000000' ; YES - CTRL6 (+/-2 Gauss) |
634 | 674 rcall I2C_TX ; send byte |
582 | 675 movlw b'00000000' ; CTRL7 Continuous Mode |
634 | 676 rcall I2C_TX ; send byte |
623 | 677 bsf SSP1CON2,PEN ; stop condition |
634 | 678 bra WaitMSSP ; wait for TX to complete and return |
679 | |
680 ; accelerometer initializes along with magnetic sensor | |
681 | |
582 | 682 |
560 | 683 I2C_init_compass2: |
628 | 684 ; magnetic |
634 | 685 bsf SSP1CON2,SEN ; start condition |
686 rcall WaitMSSP ; wait for TX to complete | |
687 movlw 0x3C ; address | |
688 rcall I2C_TX ; send byte | |
689 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) | |
690 rcall I2C_TX ; send byte | |
691 movlw b'10000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00 | |
692 rcall I2C_TX ; send byte | |
693 movlw b'00000011' ; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR) | |
694 rcall I2C_TX ; send byte | |
695 movlw b'00010000' ; CFG_REG_C_M BDU=1 0x62 0x57 | |
696 rcall I2C_TX ; send byte | |
697 bsf SSP1CON2,PEN ; stop condition | |
698 rcall WaitMSSP ; wait for TX to complete | |
699 | |
628 | 700 ; accelerometer |
623 | 701 bsf SSP1CON2,SEN ; start condition |
634 | 702 rcall WaitMSSP ; wait for TX to complete |
628 | 703 movlw 0x32 ; address |
634 | 704 rcall I2C_TX ; send byte |
628 | 705 movlw 0x9F ; 1F with auto-increment (MSB=1) |
634 | 706 rcall I2C_TX ; send byte |
628 | 707 movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) |
634 | 708 rcall I2C_TX ; send byte |
628 | 709 movlw b'00100111' ; CTRL_REG1_A (10Hz, x,y,z = ON) |
634 | 710 rcall I2C_TX ; send byte |
628 | 711 movlw b'00000000' ; CTRL_REG2_A |
634 | 712 rcall I2C_TX ; send byte |
628 | 713 movlw b'00000000' ; CTRL_REG3_A |
634 | 714 rcall I2C_TX ; send byte |
628 | 715 movlw b'00001000' ; CTRL_REG4_A (BDU=0, +/-2g, HR=1) |
634 | 716 rcall I2C_TX ; send byte |
628 | 717 ; movlw b'00000000' ; CTRL_REG5_A |
634 | 718 ; rcall I2C_TX ; send byte |
623 | 719 bsf SSP1CON2,PEN ; stop condition |
634 | 720 bra WaitMSSP ; wait for TX to complete and return |
582 | 721 |
628 | 722 |
624 | 723 I2C_init_compass3: |
628 | 724 ; magnetic |
631 | 725 bsf SSP1CON2,SEN ; start condition |
634 | 726 rcall WaitMSSP ; wait for TX to complete |
631 | 727 movlw 0x3C ; address |
634 | 728 rcall I2C_TX ; send byte |
631 | 729 movlw 0xA0 ; 0x20 with auto-increment (MSB=1) |
634 | 730 rcall I2C_TX ; send byte |
631 | 731 movlw b'01110000' ; CTRL_REG1_M (10Hz) 0x20 |
634 | 732 rcall I2C_TX ; send byte |
631 | 733 movlw b'01100000' ; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21 |
634 | 734 rcall I2C_TX ; send byte |
631 | 735 movlw b'01000000' ; CTRL_REG3_M (Continuous) 0x22 |
634 | 736 rcall I2C_TX ; send byte |
631 | 737 movlw b'00000000' ; CTRL_REG4_M (Z in Low-power mode) 0x23 |
634 | 738 rcall I2C_TX ; send byte |
631 | 739 movlw b'00000000' ; CTRL_REG5_M 0x24 |
634 | 740 rcall I2C_TX ; send byte |
631 | 741 movlw b'00000000' ; CTRL_REG5_M 0x24 |
634 | 742 rcall I2C_TX ; send byte |
631 | 743 bsf SSP1CON2,PEN ; Stop condition |
634 | 744 rcall WaitMSSP ; wait for TX to complete |
631 | 745 |
628 | 746 ;accelerometer |
631 | 747 bsf SSP1CON2,SEN ; start condition |
634 | 748 rcall WaitMSSP ; wait for TX to complete |
631 | 749 movlw 0x3A ; address |
634 | 750 rcall I2C_TX ; send byte |
628 | 751 movlw 0x20 |
634 | 752 rcall I2C_TX ; send byte |
631 | 753 movlw b'10010111' ; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20 |
634 | 754 rcall I2C_TX ; send byte |
631 | 755 movlw b'00000000' ; CTRL_REG2_A 0x21 |
634 | 756 rcall I2C_TX ; send byte |
631 | 757 movlw b'00000000' ; CTRL_REG3_A 0x22 |
634 | 758 rcall I2C_TX ; send byte |
631 | 759 movlw b'11001100' ; CTRL_REG4_A 0x23 |
634 | 760 rcall I2C_TX ; send byte |
761 bsf SSP1CON2,PEN ; stop condition | |
762 bra WaitMSSP ; wait for TX to complete and return | |
628 | 763 |
582 | 764 |
634 | 765 ;----------------------------------------------------------------------------- |
766 ; Deactivate Compass / Accelerometer | |
767 ; | |
582 | 768 global I2C_sleep_compass |
0 | 769 I2C_sleep_compass: |
628 | 770 btfss compass_enabled ; compass active? |
634 | 771 return ; NO - done |
623 | 772 bcf compass_enabled |
628 | 773 btfsc compass_type3 ; compass 3 ? |
624 | 774 bra I2C_sleep_compass3 ; YES |
628 | 775 btfsc compass_type2 ; compass 2 ? |
623 | 776 bra I2C_sleep_compass2 ; YES |
628 | 777 btfsc compass_type1 ; compass 1 ? |
623 | 778 bra I2C_sleep_compass1 ; YES |
628 | 779 ;bra I2C_sleep_compass0 ; NO - must be compass 0 then |
780 | |
634 | 781 |
560 | 782 I2C_sleep_compass0: |
628 | 783 ; magnetic |
623 | 784 bsf SSP1CON2,SEN ; start condition |
634 | 785 rcall WaitMSSP ; wait for TX to complete |
582 | 786 movlw 0x3C ; address |
634 | 787 rcall I2C_TX ; send byte |
788 movlw 0x00 ; ?? | |
789 rcall I2C_TX ; send byte | |
582 | 790 movlw b'01101000' ; ConfigA |
634 | 791 rcall I2C_TX ; send byte |
582 | 792 movlw b'00100000' ; ConfigB |
634 | 793 rcall I2C_TX ; send byte |
623 | 794 movlw b'00000010' ; idle mode |
634 | 795 rcall I2C_TX ; send byte |
623 | 796 bsf SSP1CON2,PEN ; stop condition |
634 | 797 rcall WaitMSSP ; wait for TX to complete |
631 | 798 |
634 | 799 I2C_sleep_accelerometer0: |
628 | 800 ; accelerometer |
801 bsf SSP1CON2,SEN ; start condition | |
634 | 802 rcall WaitMSSP ; wait for TX to complete |
628 | 803 movlw 0x38 ; address |
634 | 804 rcall I2C_TX ; send byte |
628 | 805 movlw 0x2A ; CTRL_REG1 |
634 | 806 rcall I2C_TX ; send byte |
628 | 807 movlw b'00000000' ; standby mode |
634 | 808 rcall I2C_TX ; send byte |
628 | 809 bsf SSP1CON2,PEN ; stop condition |
634 | 810 bra WaitMSSP ; wait for TX to complete and return |
811 | |
0 | 812 |
427 | 813 I2C_sleep_compass1: |
623 | 814 bsf SSP1CON2,SEN ; start condition |
634 | 815 rcall WaitMSSP ; wait for TX to complete |
582 | 816 movlw 0x3C ; address |
634 | 817 rcall I2C_TX ; send byte |
582 | 818 movlw 0x20 ; CTRL_REG1 |
634 | 819 rcall I2C_TX ; send byte |
623 | 820 movlw b'00000000' ; data for CTRL_REG1: acceleration sensor power-down mode |
634 | 821 rcall I2C_TX ; send byte |
623 | 822 bsf SSP1CON2,PEN ; stop condition |
634 | 823 rcall WaitMSSP ; wait for TX to complete |
623 | 824 bsf SSP1CON2,SEN ; start condition |
634 | 825 rcall WaitMSSP ; wait for TX to complete |
582 | 826 movlw 0x3C ; address |
634 | 827 rcall I2C_TX ; send byte |
582 | 828 movlw 0x26 ; CTRL_REG7 |
634 | 829 rcall I2C_TX ; send byte |
623 | 830 movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode |
634 | 831 rcall I2C_TX ; send byte |
623 | 832 bsf SSP1CON2,PEN ; stop condition |
634 | 833 bra WaitMSSP ; wait for TX to complete and return |
834 | |
835 ; accelerometer sleeps with magnetic sensor | |
631 | 836 |
560 | 837 |
838 I2C_sleep_compass2: | |
623 | 839 ; magnetic |
840 bsf SSP1CON2,SEN ; start condition | |
634 | 841 rcall WaitMSSP ; wait for TX to complete |
623 | 842 movlw 0x3C ; address |
634 | 843 rcall I2C_TX ; send byte |
623 | 844 movlw 0xE0 ; 0x60 with auto-increment (MSB=1) |
634 | 845 rcall I2C_TX ; send byte |
623 | 846 movlw b'00000011' ; CFG_REG_A_M 0x60 (idle mode)) |
634 | 847 rcall I2C_TX ; send byte |
623 | 848 movlw b'00000100' ; CFG_REG_B_M 0x61 (set pulse is released only at power-on after PD condition) |
634 | 849 rcall I2C_TX ; send byte |
623 | 850 movlw b'01010001' ; CFG_REG_C_M 0x62 |
634 | 851 rcall I2C_TX ; send byte |
623 | 852 movlw b'00000000' ; INT_CTRL_REG_M 0x63 |
634 | 853 rcall I2C_TX ; send byte |
623 | 854 bsf SSP1CON2,PEN ; stop condition |
634 | 855 rcall WaitMSSP ; wait for TX to complete |
582 | 856 |
623 | 857 ; accelerometer |
858 bsf SSP1CON2,SEN ; start condition | |
634 | 859 rcall WaitMSSP ; wait for TX to complete |
623 | 860 movlw 0x32 ; address |
634 | 861 rcall I2C_TX ; send byte |
623 | 862 movlw 0x9F ; 1F with auto-increment (MSB=1) |
634 | 863 rcall I2C_TX ; send byte |
623 | 864 movlw b'00000000' ; TEMP_CFG_REG_A 0x1F (temp sensor off) |
634 | 865 rcall I2C_TX ; send byte |
623 | 866 movlw b'00000000' ; CTRL_REG1_A 0x20 (all off) |
634 | 867 rcall I2C_TX ; send byte |
623 | 868 bsf SSP1CON2,PEN ; stop condition |
634 | 869 bra WaitMSSP ; wait for TX to complete and return |
870 | |
623 | 871 |
628 | 872 I2C_sleep_compass3: |
873 ; magnetic | |
874 bsf SSP1CON2,SEN ; start condition | |
634 | 875 rcall WaitMSSP ; wait for TX to complete |
628 | 876 movlw 0x3C ; address |
634 | 877 rcall I2C_TX ; send byte |
628 | 878 movlw 0xA2 ; 0x22 with auto-increment (MSB=1) |
634 | 879 rcall I2C_TX ; send byte |
628 | 880 movlw b'01000010' ; CTRL_REG3_M (power-down) 0x22 |
634 | 881 rcall I2C_TX ; send byte |
628 | 882 bsf SSP1CON2,PEN ; stop condition |
634 | 883 rcall WaitMSSP ; wait for TX to complete |
628 | 884 |
885 ; accelerometer | |
886 bsf SSP1CON2,SEN ; start condition | |
634 | 887 rcall WaitMSSP ; wait for TX to complete |
628 | 888 movlw 0x3A ; address |
634 | 889 rcall I2C_TX ; send byte |
624 | 890 movlw 0x20 |
634 | 891 rcall I2C_TX ; send byte |
628 | 892 movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20 |
634 | 893 rcall I2C_TX ; send byte |
628 | 894 bsf SSP1CON2,PEN ; stop condition |
634 | 895 bra WaitMSSP ; wait for TX to complete and return |
896 | |
0 | 897 |
634 | 898 ;----------------------------------------------------------------------------- |
899 ; Helper Function - wait for TX to complete | |
900 ; | |
615 | 901 WaitMSSP: |
634 | 902 clrf i2c_temp1 ; wait for max 256 loops |
903 WaitMSSP_loop: | |
904 decfsz i2c_temp1,F ; decrement loop counter, timeout? | |
905 bra WaitMSSP2 ; NO | |
906 bra I2CFail ; YES | |
615 | 907 WaitMSSP2: |
634 | 908 btfss PIR1,SSP1IF ; TX completed? |
909 bra WaitMSSP_loop ; NO - loop | |
910 bcf PIR1,SSP1IF ; YES - clear TX completion flag | |
911 return ; - done | |
912 | |
615 | 913 |
634 | 914 ;----------------------------------------------------------------------------- |
915 ; Helper Function - check for Acknowledge by Receiver | |
916 ; | |
917 I2C_Check_ACK: | |
628 | 918 btfss SSP1CON2,ACKSTAT ; ACK received from slave? |
634 | 919 return ; YES - done |
920 ;bra I2CFail ; NO - do some clean up | |
921 | |
922 | |
923 ;----------------------------------------------------------------------------- | |
924 ; Helper Function - clean up I2C Interface after missing Acknowledge | |
925 ; | |
926 I2CFail: | |
927 bsf active_reset_ostc_rx ; reset RX circuitry (which may be the cause for the hang up) | |
928 rcall I2CReset ; reset I2C | |
929 bcf PIR1,SSP1IF ; clear TX completion flag | |
930 bsf i2c_error_flag ; set error flag | |
931 bcf active_reset_ostc_rx ; release reset from RX circuitry | |
932 return ; done | |
615 | 933 |
634 | 934 |
935 ;----------------------------------------------------------------------------- | |
936 ; Helper Function - Reset I2C Module | |
937 ; | |
938 ; recover in case something went wrong, i.g. slave holds SDA low | |
939 ; | |
940 I2CReset: | |
941 clrf SSP1CON1 ; reset entire module | |
942 clrf SSP1CON2 ; ... | |
943 clrf SSP1STAT ; ... | |
944 bcf TRISC,3 ; SCL as OUTPUT | |
945 bsf TRISC,4 ; SDA as input | |
946 bcf PORTC,3 ; SCL = 0 | |
947 movlw d'9' ; clock-out 9 clock cycles manually | |
948 movwf i2c_temp1 ; ... | |
615 | 949 I2CReset_1: |
950 bsf PORTC,3 ; SCL = 1 | |
634 | 951 nop ; pause for 4 CPU cycles |
952 nop ; ... | |
953 nop ; ... | |
954 nop ; ... | |
615 | 955 btfsc PORTC,4 ; SDA = 1 ? |
634 | 956 bra I2CReset_2 ; YES - SDA has been released from slave |
615 | 957 bcf PORTC,3 ; NO - set SCL = 0 |
634 | 958 nop ; - pause for 2 CPU cycles |
959 nop ; - ... | |
960 bcf PORTC,3 ; - SCL = 0 | |
961 nop ; - pause for 2 CPU cycles | |
962 nop ; - ... | |
963 decfsz i2c_temp1,F ; - clock counter, all cycles done? | |
964 bra I2CReset_1 ; NO - loop | |
615 | 965 I2CReset_2: |
634 | 966 bsf TRISC,3 ; SCL as input |
967 clrf SSP1CON1 ; setup I2C mode | |
968 WAITMS d'10' ; wait 10 ms (reset-timeout for I2C devices) | |
969 movlw b'00000000' ; enable slew rate control | |
970 movwf SSP1STAT ; ... | |
971 movlw b'00101000' ; configure I2C module | |
972 movwf SSP1CON1 ; ... | |
973 movlw b'00000000' ; ... | |
974 movwf SSP1CON2 ; ... | |
975 movlw 0x9C ; ... | |
976 movwf SSP1ADD ; ... | |
977 return ; done | |
623 | 978 |
979 | |
634 | 980 ;----------------------------------------------------------------------------- |
981 ; Helper Function - Initialize Gauge IC again after an UVLO Event | |
982 ; | |
556
dd28d4efd4d2
fix a potential issue in the battery managment
heinrichsweikamp
parents:
498
diff
changeset
|
983 lt2942_init_again: |
623 | 984 movlw 0x02 ; point to accumulated charge registers |
634 | 985 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
623 | 986 movff battery_accumulated_charge+1,SSP1BUF ; data byte |
634 | 987 rcall WaitMSSP ; wait for TX to complete |
988 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 989 movff battery_accumulated_charge+0,SSP1BUF ; data byte |
634 | 990 rcall WaitMSSP ; wait for TX to complete |
991 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 992 bsf SSP1CON2,PEN ; stop condition |
634 | 993 rcall WaitMSSP ; wait for TX to complete |
994 MOVII battery_accumulated_charge,sub_a ; copy result to sub_a | |
995 ;bra lt2942_init ; and initialize again... | |
560 | 996 |
628 | 997 |
634 | 998 ;----------------------------------------------------------------------------- |
999 ; Initialize Gauge IC | |
1000 ; | |
582 | 1001 global lt2942_init |
634 | 1002 lt2942_init: |
623 | 1003 movlw 0x01 ; point to control reg B |
634 | 1004 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
623 | 1005 movlw b'11111000' ; automatic conversion every two seconds |
640 | 1006 movwf SSP1BUF ; data byte |
634 | 1007 rcall WaitMSSP ; wait for TX to complete |
1008 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1009 bsf SSP1CON2,PEN ; stop condition |
634 | 1010 bra WaitMSSP ; wait for TX to complete and return |
113 | 1011 |
640 | 1012 ;----------------------------------------------------------------------------- |
1013 ; Sleep Gauge IC | |
1014 ; | |
1015 global lt2942_sleep | |
1016 lt2942_sleep: | |
1017 movlw 0x01 ; point to control reg B | |
1018 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC | |
1019 movlw b'00111000' ; sleep | |
1020 movwf SSP1BUF ; data byte | |
1021 rcall WaitMSSP ; wait for TX to complete | |
1022 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
1023 bsf SSP1CON2,PEN ; stop condition | |
1024 bra WaitMSSP ; wait for TX to complete and return | |
628 | 1025 |
634 | 1026 ;----------------------------------------------------------------------------- |
1027 ; Read Gauge IC - Status Register | |
1028 ; | |
113 | 1029 global lt2942_get_status |
634 | 1030 lt2942_get_status: |
623 | 1031 bcf battery_gauge_available ; clear flag |
1032 movlw 0x00 ; point to status register | |
634 | 1033 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
1034 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
1035 movff SSP1BUF,WREG ; copy received byte to WREG | |
582 | 1036 btfss WREG,7 ; 2942 found? |
623 | 1037 bsf battery_gauge_available ; YES - set flag |
1038 bsf SSP1CON2,PEN ; stop condition | |
634 | 1039 bra WaitMSSP ; wait for TX to complete and return |
113 | 1040 |
1041 | |
634 | 1042 ;----------------------------------------------------------------------------- |
1043 ; Read Gauge IC - Voltage | |
1044 ; | |
113 | 1045 global lt2942_get_voltage |
634 | 1046 lt2942_get_voltage: |
623 | 1047 movlw 0x08 ; point to voltage registers |
634 | 1048 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
1049 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
623 | 1050 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1051 rcall WaitMSSP ; wait for TX to complete |
1052 movff SSP1BUF,xA+1 ; copy received byte to xA+1 | |
1053 bsf SSP1CON2,RCEN ; enable receive mode | |
1054 rcall WaitMSSP ; wait for TX to complete | |
1055 movff SSP1BUF,xA+0 ; copy received byte to xA+0 | |
623 | 1056 bsf SSP1CON2,PEN ; stop condition |
634 | 1057 rcall WaitMSSP ; wait for TX to complete |
615 | 1058 |
623 | 1059 ; convert voltage from raw value to Volt |
1060 MOVLI .6000,xB ; load conversion multiplicand into xB | |
1061 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
1062 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
1063 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 | |
1064 movff xC+3,batt_voltage+1 ; ... | |
615 | 1065 |
623 | 1066 tstfsz batt_voltage+1 ; < 256 mV ? |
1067 return ; NO - done | |
634 | 1068 bra lt2942_init ; YES - initialize gauge and return |
623 | 1069 |
615 | 1070 |
634 | 1071 ;----------------------------------------------------------------------------- |
1072 ; Read Gauge IC - Temperature | |
1073 ; | |
623 | 1074 global lt2942_get_temperature |
1075 lt2942_get_temperature: ; read battery temperature | |
1076 movlw 0x0C ; point to temperature register | |
634 | 1077 call I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
1078 call I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
623 | 1079 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1080 rcall WaitMSSP ; wait for TX to complete |
623 | 1081 movff SSP1BUF,xA+1 ; store raw temperature, high byte |
628 | 1082 bsf SSP1CON2,RCEN ; enable receive mode |
634 | 1083 rcall WaitMSSP ; wait for TX to complete |
623 | 1084 movff SSP1BUF,xA+0 ; store raw temperature, low byte |
1085 bsf SSP1CON2,PEN ; stop condition | |
634 | 1086 rcall WaitMSSP ; wait for TX to complete |
623 | 1087 |
1088 ; convert temperature from raw value to Kelvin | |
1089 MOVLI .6000,xB ; load conversion multiplicand into xB | |
1090 call mult16x16 ; xC = xA * xB -> multiply raw value in xA with conversion multiplicand | |
1091 ; divide by 65536 instead of 65535, introducing an error of 65536/65535 = 0.002 % | |
1092 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 | |
1093 movff xC+3,battery_temperature+1 ; ... | |
1094 | |
634 | 1095 ; check if battery is being charged right now |
623 | 1096 btfss cc_active ; in CC charging mode? |
1097 return ; NO - not charging, done | |
1098 | |
640 | 1099 ; ignore false readings (>125°C) |
1100 movlw LOW .3307 | |
1101 movwf sub_a+0 | |
1102 movlw HIGH .3307 | |
1103 movwf sub_a+1 | |
1104 MOVII battery_temperature, sub_b | |
1105 call cmpU16 ; sub_a - sub_b (with UNSIGNED values) | |
1106 btfsc neg_flag ; result negative? | |
1107 return ; YES - temperature > 125°C, not possible here. Skip test. | |
1108 | |
623 | 1109 ; check for over-temperature while charging |
1110 MOVLI max_battery_charge_temp,sub_a | |
1111 MOVII battery_temperature, sub_b | |
1112 call cmpU16 ; sub_a - sub_b (with UNSIGNED values) | |
1113 btfss neg_flag ; result negative? | |
1114 return ; NO - temperature <= threshold, ok, done | |
640 | 1115 return |
623 | 1116 ; YES - too hot, disable charging circuitry |
1117 bsf charge_disable ; - set charging-inhibit signal | |
1118 bcf charge_enable ; - activate charging-inhibit signal | |
1119 bsf battery_overtemp ; - flag that the battery charging over-temperature protection has tripped | |
634 | 1120 return ; - done |
623 | 1121 |
113 | 1122 |
634 | 1123 ;----------------------------------------------------------------------------- |
1124 ; Read Gauge IC - Read State of Charge | |
1125 ; | |
113 | 1126 global lt2942_get_accumulated_charge |
623 | 1127 lt2942_get_accumulated_charge: ; read accumulated charge and compute percent |
1128 movlw 0x00 ; point to status register | |
634 | 1129 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
1130 rcall I2C_RX_GAUGE ; receive byte from the LT2942 Gauge IC | |
623 | 1131 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1132 rcall WaitMSSP ; wait for TX to complete |
1133 movff SSP1BUF,gauge_status_byte ; copy received byte to gauge_status_byte | |
466 | 1134 |
634 | 1135 bsf SSP1CON2,RCEN ; enable receive mode |
1136 rcall WaitMSSP ; wait for TX to complete ; dummy read (control byte) | |
1137 movf SSP1BUF,W ; dump to WREG | |
623 | 1138 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1139 rcall WaitMSSP ; wait for TX to complete |
582 | 1140 |
634 | 1141 bsf SSP1CON2,RCEN ; enable receive mode |
1142 rcall WaitMSSP ; wait for TX to complete | |
1143 movff SSP1BUF,sub_a+1 ; copy received byte to sub_a+1 | |
623 | 1144 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1145 rcall WaitMSSP ; wait for TX to complete |
582 | 1146 |
634 | 1147 bsf SSP1CON2,RCEN ; enable receive mode |
1148 rcall WaitMSSP ; wait for TX to complete | |
1149 movff SSP1BUF,sub_a+0 ; copy received byte to sub_a+0 | |
623 | 1150 bsf SSP1CON2,PEN ; stop condition |
634 | 1151 rcall WaitMSSP ; wait for TX to complete |
113 | 1152 |
623 | 1153 btfsc gauge_status_byte,0 ; UVLO event ? |
634 | 1154 rcall lt2942_init_again ; YES - do an re-initialization |
623 | 1155 |
1156 MOVII sub_a,battery_accumulated_charge ; save raw value | |
582 | 1157 |
634 | 1158 ; Compute batt_percent = (charge - battery_offset) / 365 |
1159 MOVII battery_offset,sub_b ; get battery offset | |
582 | 1160 call subU16 ; sub_c = sub_a - sub_b (with signed values) |
634 | 1161 clrf batt_percent ; default batt_percent to zero |
582 | 1162 btfsc neg_flag ; result negative? |
623 | 1163 bra lt2942_set_to_zero_percent ; YES - keep LT2942 at zero percent and return |
113 | 1164 |
623 | 1165 ; > zero, set batt_percent properly |
634 | 1166 MOVII sub_c,xA ; copy net charge to xA |
1167 MOVII battery_capacity,xB ; get battery capacity into xB | |
604 | 1168 call div16x16 ; xC = xA / xB with xA as remainder |
634 | 1169 movff xC+0,batt_percent ; result is battery percentage |
628 | 1170 movlw .100 ; max. value is 100 % |
1171 cpfslt batt_percent ; batt_percent < 100 % ? | |
1172 movwf batt_percent ; NO - limit to 100 % | |
631 | 1173 return ; done |
113 | 1174 |
449 | 1175 lt2942_set_to_zero_percent: |
623 | 1176 movlw 0x02 ; point to accumulated charge registers |
634 | 1177 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
1178 movff battery_offset+1,SSP1BUF ; send battery offset, high byte | |
1179 rcall WaitMSSP ; wait for TX to complete | |
1180 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
1181 movff battery_offset+0,SSP1BUF ; send battery offset, low byte | |
1182 rcall WaitMSSP ; wait for TX to complete | |
1183 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1184 bsf SSP1CON2,PEN ; stop condition |
634 | 1185 bra WaitMSSP ; wait for TX to complete and return |
449 | 1186 |
628 | 1187 |
634 | 1188 ;----------------------------------------------------------------------------- |
1189 ; Read Gauge IC - Reset Accumulating Register to 0xFFFF | |
1190 ; | |
113 | 1191 global lt2942_charge_done |
634 | 1192 lt2942_charge_done: |
623 | 1193 movlw 0x02 ; point to accumulated charge registers |
634 | 1194 rcall I2C_TX_GAUGE ; send byte to the LT2942 gauge IC |
623 | 1195 setf SSP1BUF ; data byte |
634 | 1196 rcall WaitMSSP ; wait for TX to complete |
1197 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1198 setf SSP1BUF ; data byte |
634 | 1199 rcall WaitMSSP ; wait for TX to complete |
1200 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1201 bsf SSP1CON2,PEN ; stop condition |
634 | 1202 bra WaitMSSP ; wait for TX to complete and return |
1203 | |
113 | 1204 |
634 | 1205 ;----------------------------------------------------------------------------- |
1206 ; Helper Function - send 1 Byte to the LT2942 Gauge IC | |
1207 ; | |
1208 I2C_TX_GAUGE: | |
1209 movwf i2c_temp2 ; save data byte to be sent | |
623 | 1210 bsf SSP1CON2,SEN ; start condition |
634 | 1211 rcall WaitMSSP ; wait for TX to complete |
623 | 1212 movlw b'11001000' ; address byte + Write bit |
582 | 1213 movwf SSP1BUF ; control byte |
634 | 1214 rcall WaitMSSP ; wait for TX to complete |
1215 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
1216 movf i2c_temp2,W ; restore data byte to be sent | |
1217 bra I2C_TX ; send byte and return | |
582 | 1218 |
634 | 1219 |
1220 ;----------------------------------------------------------------------------- | |
1221 ; Helper Function - receive 1 Byte from the LT2942 Gauge IC | |
1222 ; | |
113 | 1223 I2C_RX_GAUGE: |
623 | 1224 bsf SSP1CON2,SEN ; start condition |
634 | 1225 rcall WaitMSSP ; wait for TX to complete |
623 | 1226 movlw b'11001001' ; address byte + Read bit |
582 | 1227 movwf SSP1BUF ; control byte |
634 | 1228 rcall WaitMSSP ; wait for TX to complete |
1229 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
628 | 1230 bsf SSP1CON2,RCEN ; enable receive mode |
634 | 1231 bra WaitMSSP ; wait for reception and return |
1232 | |
1233 | |
1234 ;----------------------------------------------------------------------------- | |
1235 ; Reset Hardware and Software Battery Gauge | |
1236 ; | |
1237 ; called from comm.asm and menu_tree.asm | |
1238 ; | |
1239 global reset_battery_gauge_and_lt2942 | |
1240 reset_battery_gauge_and_lt2942: | |
1241 btfsc battery_gauge_available ; battery gauge chip available? | |
1242 call lt2942_charge_done ; YES - reset meter to 0xFFFF | |
1243 ;bra reset_battery_gauge ; continue resetting gauge registers | |
582 | 1244 |
1245 | |
634 | 1246 ;----------------------------------------------------------------------------- |
1247 ; Reset Software Battery Gauge | |
1248 ; | |
631 | 1249 global reset_battery_gauge |
634 | 1250 reset_battery_gauge: |
1251 bsf block_battery_gauge ; suspend ISR from accessing the battery registers | |
1252 movlw .100 ; set battery level to 100% | |
1253 movwf batt_percent ; ... | |
1254 banksel battery_gauge ; select bank ISR data | |
1255 clrf battery_gauge+0 ; null the battery registers | |
1256 clrf battery_gauge+1 ; ... | |
1257 clrf battery_gauge+2 ; ... | |
1258 clrf battery_gauge+3 ; ... | |
1259 clrf battery_gauge+4 ; ... | |
1260 clrf battery_gauge+5 ; ... | |
1261 banksel common ; back to bank common | |
1262 goto eeprom_battery_gauge_write ; update battery registers in EEPROM, unblock ISR and return | |
631 | 1263 |
1264 | |
634 | 1265 |
604 | 1266 IFDEF _rx_functions |
1267 | |
634 | 1268 ;----------------------------------------------------------------------------- |
1269 ; OSTC TR - probe if TR Module available | |
1270 ; | |
560 | 1271 global I2C_probe_OSTC_rx |
1272 I2C_probe_OSTC_rx: | |
634 | 1273 bcf ostc_rx_present ; default to no TR module available |
623 | 1274 clrf WREG ; bank-safe set to zero of ... |
1275 movff WREG,rx_firmware_cur_major ; ... current TR module firmware, major | |
1276 movff WREG,rx_firmware_cur_minor ; ... current TR module firmware, minor | |
1277 movlw .5 ; max number of tries for detecting a TR module | |
634 | 1278 movwf hy ; initialize loop counter for tries |
604 | 1279 I2C_probe_OSTC_rx_1: |
623 | 1280 bsf SSP1CON2,SEN ; start condition |
634 | 1281 rcall WaitMSSP ; wait for TX to complete |
623 | 1282 movlw 0x50 ; address byte + write bit |
582 | 1283 movwf SSP1BUF ; control byte |
634 | 1284 rcall WaitMSSP ; wait for TX to complete |
623 | 1285 btfss SSP1CON2,ACKSTAT ; ACK received? |
1286 bsf ostc_rx_present ; YES - TR module detected | |
1287 bsf SSP1CON2,PEN ; stop condition | |
634 | 1288 rcall WaitMSSP ; wait for TX to complete |
623 | 1289 btfss ostc_rx_present ; was a TR module detected? |
1290 return ; NO - done | |
634 | 1291 |
1292 WAITMS .1 ; wait 1 ms | |
1293 | |
623 | 1294 bsf SSP1CON2,SEN ; start condition |
634 | 1295 rcall WaitMSSP ; wait for TX to complete |
623 | 1296 movlw 0x50 ; address byte + write bit |
582 | 1297 movwf SSP1BUF ; control byte |
634 | 1298 rcall WaitMSSP ; wait for TX to complete |
1299 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
1300 movlw 0x1B ; command: get firmware | |
1301 movwf SSP1BUF ; send command | |
1302 rcall WaitMSSP ; wait for TX to complete | |
1303 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1304 bsf SSP1CON2,PEN ; stop condition |
634 | 1305 rcall WaitMSSP ; wait for TX to complete |
1306 | |
1307 WAITMS .1 ; wait 1 ms | |
1308 | |
623 | 1309 bsf SSP1CON2,SEN ; start condition |
634 | 1310 rcall WaitMSSP ; wait for TX to complete |
623 | 1311 movlw 0x51 ; address byte + Read bit |
582 | 1312 movwf SSP1BUF ; control byte |
634 | 1313 rcall WaitMSSP ; wait for TX to complete |
623 | 1314 bsf SSP1CON2,RCEN ; enable receive mode |
634 | 1315 rcall WaitMSSP ; wait for TX to complete |
623 | 1316 movff SSP1BUF,rx_firmware_cur_major ; store as firmware version, major |
1317 bsf SSP1CON2,ACKEN ; master acknowledge | |
634 | 1318 rcall WaitMSSP ; wait for TX to complete |
582 | 1319 |
560 | 1320 ; last byte in read from RX circuity always with a NACK! |
623 | 1321 bsf SSP1CON2,RCEN ; enable receive mode |
634 | 1322 rcall WaitMSSP ; wait for TX to complete |
623 | 1323 movff SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor |
634 | 1324 bsf SSP1CON2,ACKDT ; set ACKDT flag |
623 | 1325 bsf SSP1CON2,ACKEN ; master NOT acknowledge |
634 | 1326 rcall WaitMSSP ; wait for TX to complete |
623 | 1327 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
1328 bsf SSP1CON2,PEN ; stop condition | |
634 | 1329 rcall WaitMSSP ; wait for TX to complete |
604 | 1330 |
623 | 1331 ; wait for TR module becoming ready |
634 | 1332 movff rx_firmware_cur_minor,i2c_temp1 ; copy minor firmware version to bank common |
623 | 1333 movlw .147 ; code for not ready, minor |
1334 cpfseq i2c_temp1 ; equal? | |
634 | 1335 return ; NO - TR module ready, done |
1336 movff rx_firmware_cur_major,i2c_temp1 ; YES - copy major firmware version to bank common | |
623 | 1337 movlw .27 ; - code for not ready, major |
1338 cpfseq i2c_temp1 ; - equal? | |
634 | 1339 return ; NO - TR module ready, done |
623 | 1340 bsf active_reset_ostc_rx ; YES - apply reset to TR module |
1341 WAITMS .5 ; - wait 5 ms | |
1342 bcf active_reset_ostc_rx ; - release reset | |
1343 WAITMS .250 ; - wait for 250 ms | |
1344 WAITMS .250 ; - wait another 250 ms | |
1345 decfsz hy,F ; - decrement counter for number of tries, became zero? | |
1346 bra I2C_probe_OSTC_rx_1 ; - NO - try again | |
1347 bcf ostc_rx_present ; - YES - something is wrong, flag TR module as not available | |
634 | 1348 return ; - done |
582 | 1349 |
560 | 1350 |
634 | 1351 ;----------------------------------------------------------------------------- |
1352 ; OSTC TR - get Tank Data | |
1353 ; | |
560 | 1354 global I2C_get_tankdata |
1355 I2C_get_tankdata: | |
623 | 1356 bsf SSP1CON2,SEN ; start condition |
634 | 1357 rcall WaitMSSP ; wait for TX to complete |
623 | 1358 movlw 0x50 ; address byte + write bit |
582 | 1359 movwf SSP1BUF ; control byte |
634 | 1360 rcall WaitMSSP ; wait for TX to complete |
1361 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1362 movlw 0x1E ; read buffer2 (48 bytes) |
1363 movwf SSP1BUF ; data byte | |
634 | 1364 rcall WaitMSSP ; wait for TX to complete |
1365 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1366 bsf SSP1CON2,PEN ; stop condition |
634 | 1367 rcall WaitMSSP ; wait for TX to complete |
1368 | |
1369 WAITMS .1 ; wait 1 ms | |
1370 | |
560 | 1371 ; read 48 bytes |
623 | 1372 bsf SSP1CON2,SEN ; start condition |
634 | 1373 rcall WaitMSSP ; wait for TX to complete |
623 | 1374 movlw 0x51 ; address byte + read bit |
582 | 1375 movwf SSP1BUF ; control byte |
634 | 1376 rcall WaitMSSP ; wait for TX to complete |
1377 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
582 | 1378 movlw .47 ; 47 with ACK + 1 w/o ACK |
634 | 1379 movwf i2c_temp2 ; initialize loop counter |
1380 lfsr FSR2,rx_buffer ; point to start of rx data buffer | |
560 | 1381 I2C_get_tankdata_loop_read: |
634 | 1382 bsf SSP1CON2,RCEN ; enable receive mode |
1383 rcall WaitMSSP ; wait for TX to complete | |
1384 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer | |
1385 bcf SSP1CON2,ACKDT ; reset ACKDT flag | |
623 | 1386 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1387 rcall WaitMSSP ; wait for TX to complete |
1388 decfsz i2c_temp2,F ; decrement loop counter, done? | |
1389 bra I2C_get_tankdata_loop_read ; NO - loop | |
1390 ; read last byte without ACK | |
1391 bsf SSP1CON2,RCEN ; enable receive mode | |
1392 rcall WaitMSSP ; wait for TX to complete | |
1393 movff SSP1BUF,POSTINC2 ; copy received byte to the rx buffer | |
1394 bsf SSP1CON2,ACKDT ; set ACKDT flag | |
623 | 1395 bsf SSP1CON2,ACKEN ; master NOT acknowledge |
634 | 1396 rcall WaitMSSP ; wait for TX to complete |
623 | 1397 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
1398 bsf SSP1CON2,PEN ; stop condition | |
634 | 1399 bra WaitMSSP ; wait for TX to complete and return |
582 | 1400 |
1401 | |
634 | 1402 ;----------------------------------------------------------------------------- |
1403 ; OSTC TR - Firmware Update | |
1404 ; | |
628 | 1405 IFDEF _rx_update |
1406 | |
560 | 1407 global I2C_update_OSTC_rx |
623 | 1408 I2C_update_OSTC_rx: ; transfer 64 byte to RX co-processor |
1409 ; setup for write | |
582 | 1410 bcf i2c_error_flag ; clear error flag |
623 | 1411 lfsr FSR2,buffer ; initialize pointer to send buffer used for verify |
1412 movlw .64 ; initialize loop counter: 64 byte with ACK | |
1413 movwf i2c_temp2 ; ... | |
1414 ; address write | |
1415 bsf SSP1CON2,SEN ; start condition | |
634 | 1416 rcall WaitMSSP ; wait for TX to complete |
623 | 1417 movlw 0x50 ; address byte + write bit |
582 | 1418 movwf SSP1BUF ; control byte |
634 | 1419 rcall WaitMSSP ; wait for TX to complete |
1420 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1421 ; write 64 bytes |
1422 I2C_update_OSTC_loop: | |
1423 TBLRD*+ ; read a byte from program memory | |
1424 movff TABLAT,POSTINC2 ; copy to send buffer | |
1425 movff TABLAT,SSP1BUF ; copy to I2C data buffer | |
634 | 1426 rcall WaitMSSP ; wait for TX to complete |
1427 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1428 decfsz i2c_temp2,F ;decrement loop counter, became zero? |
1429 bra I2C_update_OSTC_loop ; NO - loop | |
1430 bsf SSP1CON2,PEN ; YES - stop condition | |
634 | 1431 rcall WaitMSSP ; - wait for TX to complete |
623 | 1432 WAITMS .1 ; - wait another 1 ms |
1433 ; setup for read-back | |
1434 lfsr FSR2,buffer ; reset pointer to begin of send buffer | |
1435 movlw .63 ; initialize loop counter: 63 byte with ACK + 1 w/o ACK | |
634 | 1436 movwf i2c_temp2 ; ... |
623 | 1437 ; address read-back |
1438 bsf SSP1CON2,SEN ; start condition | |
634 | 1439 rcall WaitMSSP ; wait for TX to complete |
623 | 1440 movlw 0x51 ; address byte + read bit |
582 | 1441 movwf SSP1BUF ; control byte |
634 | 1442 rcall WaitMSSP ; wait for TX to complete |
1443 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1444 ; read-back 64 bytes |
560 | 1445 I2C_update_OSTC_loop_read: |
623 | 1446 bsf SSP1CON2,RCEN ; enable receive mode |
634 | 1447 rcall WaitMSSP ; wait for TX to complete |
1448 movf SSP1BUF,W ; copy received byte to WREG | |
623 | 1449 cpfseq POSTINC2 ; compare read-back byte with sent byte, equal? |
1450 bsf i2c_error_flag ; NO - not equal, set error flag | |
634 | 1451 bcf SSP1CON2,ACKDT ; reset ACKDT flag |
623 | 1452 bsf SSP1CON2,ACKEN ; master acknowledge |
634 | 1453 rcall WaitMSSP ; wait for TX to complete |
623 | 1454 decfsz i2c_temp2,F ; decrement loop counter, became zero? |
1455 bra I2C_update_OSTC_loop_read ; NO - loop | |
560 | 1456 ; 1 w/o ACK |
623 | 1457 bsf SSP1CON2, RCEN ; YES - enable receive mode |
634 | 1458 rcall WaitMSSP ; - wait for TX to complete |
623 | 1459 movf SSP1BUF,W ; - get 64th byte |
1460 cpfseq POSTINC2 ; - compare read-back byte with sent byte, equal? | |
1461 bsf i2c_error_flag ; NO - not equal, set error flag | |
634 | 1462 bsf SSP1CON2,ACKDT ; - set ACKDT flag |
623 | 1463 bsf SSP1CON2,ACKEN ; - master NOT acknowledge |
634 | 1464 rcall WaitMSSP ; - wait for TX to complete |
623 | 1465 bcf SSP1CON2,ACKDT ; - reset ACKDT flag |
1466 ; stop | |
1467 bsf SSP1CON2,PEN ; stop condition | |
634 | 1468 rcall WaitMSSP ; wait for TX to complete |
560 | 1469 WAITMS .1 |
623 | 1470 ; address commit |
1471 bsf SSP1CON2,SEN ; start condition | |
634 | 1472 rcall WaitMSSP ; wait for TX to complete |
623 | 1473 movlw 0x50 ; address byte + write bit |
582 | 1474 movwf SSP1BUF ; control byte |
634 | 1475 rcall WaitMSSP ; wait for TX to complete |
1476 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1477 movlw 0x1F ; write command |
1478 movwf SSP1BUF ; data byte | |
634 | 1479 rcall WaitMSSP ; wait for TX to complete |
1480 rcall I2C_Check_ACK ; check for acknowledge by receiver | |
623 | 1481 bsf SSP1CON2,PEN ; stop condition |
634 | 1482 rcall WaitMSSP ; wait for TX to complete |
623 | 1483 WAITMS .5 ; required waiting time |
1484 ; error check | |
1485 btfss i2c_error_flag ; did an error occur? | |
1486 retlw .0 ; NO - data transfered successfully | |
1487 retlw .255 ; YES - error in data transfer occurred | |
582 | 1488 |
628 | 1489 ENDIF ; _rx_update |
1490 | |
1491 ENDIF ; _rx_functions | |
604 | 1492 |
634 | 1493 ;----------------------------------------------------------------------------- |
623 | 1494 |
582 | 1495 END |