comparison src/i2c.asm @ 634:4050675965ea

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