Mercurial > public > hwos_code
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 |