0
|
1 ;=============================================================================
|
|
2 ;
|
|
3 ; File i2c.asm
|
|
4 ;
|
|
5 ; I2C Interface to HMC5883L and MMA8452Q
|
|
6 ;
|
|
7 ; HMC5883L's read address (8-Bit): 0x3D
|
|
8 ; HMC5883L's write address (8-Bit): 0x3C
|
|
9 ;
|
|
10 ; MMA8452Q's read address (8-Bit): 0x39
|
|
11 ; MMA8452Q's write address (8-Bit): 0x38
|
|
12 ;
|
|
13 ; Copyright (c) 2012, JD Gascuel, HeinrichsWeikamp, all right reserved.
|
|
14 ;=============================================================================
|
|
15 ; HISTORY
|
|
16 ; 2012-08-22 : [mH] Creation
|
|
17
|
|
18
|
|
19 #include "ostc3.inc" ; Mandatory header
|
|
20 #include "wait.inc"
|
|
21
|
|
22 i2c CODE
|
|
23
|
|
24 WaitMSSP:
|
|
25 decfsz i2c_temp,F ; check for timeout during I2C action
|
|
26 bra WaitMSSP2
|
|
27 bra I2CFail ; timeout occured
|
|
28 WaitMSSP2:
|
|
29 btfss PIR1,SSPIF
|
|
30 bra WaitMSSP
|
|
31 clrf i2c_temp
|
|
32 bcf PIR1,SSPIF
|
|
33 nop
|
|
34 return
|
|
35
|
|
36 I2C_WaitforACK:
|
|
37 btfss SSPCON2,ACKSTAT ; checks for ACK bit from slave
|
|
38 return
|
|
39 I2CFail:
|
|
40 rcall I2CReset ; I2C Reset
|
|
41 bcf PIR1,SSPIF
|
|
42 clrf i2c_temp
|
|
43 return
|
|
44
|
|
45 I2CReset: ; Something went wrong (Slave holds SDA low?)
|
|
46 clrf SSP1CON1 ; wake-up slave and reset entire module
|
|
47 clrf SSP1CON2
|
|
48 clrf SSP1STAT
|
|
49 bcf TRISC,3 ; SCL OUTPUT
|
|
50 bsf TRISC,4 ; SDA Input
|
|
51 bcf PORTC,3
|
|
52 movlw d'9'
|
|
53 movwf i2c_temp ; clock-out 9 clock cycles manually
|
|
54 I2CReset_1:
|
|
55 bsf PORTC,3 ; SCL=1
|
|
56 nop
|
|
57 nop
|
|
58 nop
|
|
59 nop
|
|
60 btfsc PORTC,4 ; SDA=1?
|
|
61 bra I2CReset_2 ; =1, SDA has been released from slave
|
|
62 bcf PORTC,3 ; SCL=0
|
|
63 nop
|
|
64 nop
|
|
65 bcf PORTC,3
|
|
66 nop
|
|
67 nop
|
|
68 decfsz i2c_temp,F
|
|
69 bra I2CReset_1 ; check for nine clock cycles
|
|
70 I2CReset_2:
|
|
71 bsf TRISC,3 ; SCL Input
|
|
72 clrf SSP1CON1 ; setup I²C Mode
|
|
73 WAITMS d'10' ; Reset-Timeout for I2C devices
|
|
74 movlw b'00000000' ; with slew rate control
|
|
75 movwf SSPSTAT
|
|
76 movlw b'00101000'
|
|
77 movwf SSP1CON1
|
|
78 movlw b'00000000'
|
|
79 movwf SSP1CON2
|
|
80 movlw 0x27
|
|
81 movwf SSP1ADD
|
|
82 return
|
|
83
|
|
84 I2C_TX:
|
|
85 movwf SSP1BUF
|
|
86 rcall WaitMSSP
|
|
87 bra I2C_WaitforACK ; Returns...
|
|
88
|
|
89 I2C_TwoBytesRX_div16: ; Get two bytes and devide lo:hi/16 (signed)
|
|
90 rcall I2C_OneByteRX ; Get one byte
|
|
91 movff SSP1BUF,hi ; Data Byte
|
|
92 rcall I2C_OneByteRX ; Get one byte
|
|
93 movff SSP1BUF,lo ; Data Byte
|
|
94 I2C_TwoBytesRX_div16_2: ; devide lo:hi/16 (signed) only
|
|
95 bcf STATUS,C
|
|
96 btfsc hi,7 ; Copy sign bit to carry
|
|
97 bsf STATUS,C
|
|
98 rrcf hi ; /2
|
|
99 rrcf lo
|
|
100 bcf STATUS,C
|
|
101 btfsc hi,7 ; Copy sign bit to carry
|
|
102 bsf STATUS,C
|
|
103 rrcf hi ; /4
|
|
104 rrcf lo
|
|
105 bcf STATUS,C
|
|
106 btfsc hi,7 ; Copy sign bit to carry
|
|
107 bsf STATUS,C
|
|
108 rrcf hi ; /8
|
|
109 rrcf lo
|
|
110 bcf STATUS,C
|
|
111 btfsc hi,7 ; Copy sign bit to carry
|
|
112 bsf STATUS,C
|
|
113 rrcf hi ; /16
|
|
114 rrcf lo
|
|
115 return
|
|
116
|
|
117 global I2C_RX_accelerometer
|
|
118 I2C_RX_accelerometer:
|
|
119 bsf SSP1CON2,SEN ; Start condition
|
|
120 rcall WaitMSSP
|
|
121 movlw 0x38 ; address
|
|
122 rcall I2C_TX
|
|
123 movlw 0x01
|
|
124 rcall I2C_TX
|
|
125 bsf SSP1CON2,RSEN ; Repeated start condition (!)
|
|
126 rcall WaitMSSP
|
|
127 movlw 0x39 ; address
|
|
128 rcall I2C_TX
|
|
129
|
|
130 ; Chip orientation on the PCB requires
|
|
131 ; Original = Corrected
|
|
132 ; x = -x
|
|
133 ; y = -y
|
|
134 ; z = -z
|
|
135
|
|
136
|
|
137 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed)
|
|
138 comf hi ; 16bit sign change.
|
|
139 negf lo
|
|
140 btfsc STATUS,C ; Carry to propagate ?
|
|
141 incf hi,F ; YES: do it.
|
|
142 movff lo,accel_DX+0
|
|
143 movff hi,accel_DX+1 ; Copy result
|
|
144
|
|
145 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed)
|
|
146 comf hi ; 16bit sign change.
|
|
147 negf lo
|
|
148 btfsc STATUS,C ; Carry to propagate ?
|
|
149 incf hi,F ; YES: do it.
|
|
150 movff lo,accel_DY+0
|
|
151 movff hi,accel_DY+1 ; Copy result
|
|
152
|
|
153 rcall I2C_OneByteRX ; Get one byte
|
|
154 movff SSP1BUF,hi ; Data Byte
|
|
155 bsf SSP1CON2, RCEN ; Enable recieve mode
|
|
156 rcall WaitMSSP
|
|
157 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+0)...
|
|
158 movff SSP1BUF,lo ; Data Byte
|
|
159
|
|
160 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only
|
|
161 comf hi ; 16bit sign change.
|
|
162 negf lo
|
|
163 btfsc STATUS,C ; Carry to propagate ?
|
|
164 incf hi,F ; YES: do it.
|
|
165 movff lo,accel_DZ+0
|
|
166 movff hi,accel_DZ+1 ; Copy result
|
|
167
|
|
168 bsf SSP1CON2,PEN ; Stop condition
|
|
169 rcall WaitMSSP
|
|
170 return
|
|
171
|
|
172 I2C_OneByteRX:
|
|
173 bsf SSP1CON2, RCEN ; Enable recieve mode
|
|
174 rcall WaitMSSP
|
|
175 bsf SSP1CON2,ACKEN ; Master acknowlegde
|
|
176 rcall WaitMSSP
|
|
177 return
|
|
178
|
|
179 global I2C_RX_compass
|
|
180 I2C_RX_compass:
|
|
181 bsf SSP1CON2,SEN ; Start condition
|
|
182 rcall WaitMSSP
|
|
183 movlw 0x3C ; address
|
|
184 rcall I2C_TX
|
|
185 movlw 0x03
|
|
186 rcall I2C_TX
|
|
187 bsf SSP1CON2,PEN ; Stop condition
|
|
188 rcall WaitMSSP
|
|
189
|
|
190 bcf PIR1,SSPIF
|
|
191 bsf SSP1CON2,SEN ; Start condition
|
|
192 rcall WaitMSSP
|
|
193 movlw 0x3D ; address
|
|
194 rcall I2C_TX
|
|
195
|
|
196 ; Compass IC sends data in following order:
|
|
197 ; x MSB
|
|
198 ; x LSB
|
|
199 ; z MSB
|
|
200 ; z LSB
|
|
201 ; y MSB
|
|
202 ; y LSB
|
|
203
|
|
204 ; Chip orientation on the PCB requires
|
|
205 ; Original = Corrected
|
|
206 ; x = -y
|
|
207 ; z = z
|
|
208 ; y = x
|
|
209
|
|
210 rcall I2C_OneByteRX ; Get one byte
|
|
211 movff SSP1BUF,compass_DY+1; Data Byte
|
|
212 rcall I2C_OneByteRX ; Get one byte
|
|
213 movff SSP1BUF,compass_DY+0; Data Byte
|
|
214 banksel compass_DY
|
|
215 comf compass_DY+1 ; 16bit sign change.
|
|
216 negf compass_DY+0
|
|
217 btfsc STATUS,C ; Carry to propagate ?
|
|
218 incf compass_DY+1,F ; YES: do it.
|
|
219 banksel common
|
|
220 rcall I2C_OneByteRX ; Get one byte
|
|
221 movff SSP1BUF,compass_DZ+1; Data Byte
|
|
222 rcall I2C_OneByteRX ; Get one byte
|
|
223 movff SSP1BUF,compass_DZ+0; Data Byte
|
|
224 rcall I2C_OneByteRX ; Get one byte
|
|
225 movff SSP1BUF,compass_DX+1; Data Byte
|
|
226 bsf SSP1CON2, RCEN ; Enable recieve mode
|
|
227 rcall WaitMSSP
|
|
228 movff SSP1BUF,compass_DX+0; Data Byte
|
|
229 bsf SSP1CON2,PEN ; Stop condition
|
|
230 rcall WaitMSSP
|
|
231 return
|
|
232
|
|
233 global I2C_init_compass
|
|
234 I2C_init_compass:
|
|
235 bsf SSP1CON2,SEN ; Start condition
|
|
236 rcall WaitMSSP
|
|
237 movlw 0x3C ; address
|
|
238 rcall I2C_TX
|
|
239 movlw 0x00
|
|
240 rcall I2C_TX
|
|
241 ; movlw b'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias)
|
|
242 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged
|
|
243 ; movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged
|
|
244 rcall I2C_TX
|
|
245 movlw b'00100000' ; ConfigB, 1090Gauss Gain
|
|
246 ; movlw b'10000000' ; ConfigB, 440Gauss Gain
|
|
247 rcall I2C_TX
|
|
248 movlw b'00000000' ; Continous Mode
|
|
249 rcall I2C_TX
|
|
250 bsf SSP1CON2,PEN ; Stop condition
|
|
251 rcall WaitMSSP
|
|
252 bsf compass_enabled
|
|
253 return
|
|
254
|
|
255 global I2C_init_compass_fast
|
|
256 I2C_init_compass_fast:
|
|
257 bsf SSP1CON2,SEN ; Start condition
|
|
258 rcall WaitMSSP
|
|
259 movlw 0x3C ; address
|
|
260 rcall I2C_TX
|
|
261 movlw 0x00
|
|
262 rcall I2C_TX
|
|
263 movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged
|
|
264 rcall I2C_TX
|
|
265 movlw b'00100000' ; ConfigB, 1090Gauss Gain
|
|
266 rcall I2C_TX
|
|
267 movlw b'00000000' ; Continous Mode
|
|
268 rcall I2C_TX
|
|
269 bsf SSP1CON2,PEN ; Stop condition
|
|
270 rcall WaitMSSP
|
|
271 bsf compass_enabled
|
|
272 return
|
|
273
|
|
274
|
|
275 global I2C_sleep_compass
|
|
276 I2C_sleep_compass:
|
|
277 bsf SSP1CON2,SEN ; Start condition
|
|
278 rcall WaitMSSP
|
|
279 movlw 0x3C ; address
|
|
280 rcall I2C_TX
|
|
281 movlw 0x00
|
|
282 rcall I2C_TX
|
|
283 movlw b'01101000' ; ConfigA
|
|
284 rcall I2C_TX
|
|
285 movlw b'00100000' ; ConfigB
|
|
286 rcall I2C_TX
|
|
287 movlw b'00000010' ; Idle Mode
|
|
288 rcall I2C_TX
|
|
289 bsf SSP1CON2,PEN ; Stop condition
|
|
290 rcall WaitMSSP
|
|
291 bcf compass_enabled
|
|
292 return
|
|
293
|
|
294
|
|
295 global I2C_init_accelerometer
|
|
296 I2C_init_accelerometer:
|
|
297 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode
|
|
298
|
|
299 bsf SSP1CON2,SEN ; Start condition
|
|
300 rcall WaitMSSP
|
|
301 movlw 0x38 ; address
|
|
302 rcall I2C_TX
|
|
303 movlw 0x0E ; XYZ_DATA_CFG
|
|
304 rcall I2C_TX
|
|
305 movlw b'00000000' ; High pass Filter=0 , +/- 2g range
|
|
306 rcall I2C_TX
|
|
307 bsf SSP1CON2,PEN ; Stop condition
|
|
308 rcall WaitMSSP
|
|
309
|
|
310
|
|
311 bsf SSP1CON2,SEN ; Start condition
|
|
312 rcall WaitMSSP
|
|
313 movlw 0x38 ; address
|
|
314 rcall I2C_TX
|
|
315 movlw 0x2A ; CTRL_REG1
|
|
316 rcall I2C_TX
|
|
317 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode
|
|
318 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode
|
|
319 rcall I2C_TX
|
|
320 movlw b'00000010' ; CTRL_REG2: High Res in Active mode
|
|
321 rcall I2C_TX
|
|
322 bsf SSP1CON2,PEN ; Stop condition
|
|
323 rcall WaitMSSP
|
|
324
|
|
325 bsf SSP1CON2,SEN ; Start condition
|
|
326 rcall WaitMSSP
|
|
327 movlw 0x38 ; address
|
|
328 rcall I2C_TX
|
|
329 movlw 0x2A ; CTRL_REG1
|
|
330 rcall I2C_TX
|
|
331 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode
|
|
332 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode
|
|
333 rcall I2C_TX
|
|
334 bsf SSP1CON2,PEN ; Stop condition
|
|
335 rcall WaitMSSP
|
|
336
|
|
337 return
|
|
338
|
|
339 global I2C_sleep_accelerometer
|
|
340 I2C_sleep_accelerometer:
|
|
341 bsf SSP1CON2,SEN ; Start condition
|
|
342 rcall WaitMSSP
|
|
343 movlw 0x38 ; address
|
|
344 rcall I2C_TX
|
|
345 movlw 0x2A ; CTRL_REG1
|
|
346 rcall I2C_TX
|
|
347 movlw b'00000000' ; St. By Mode
|
|
348 rcall I2C_TX
|
|
349 bsf SSP1CON2,PEN ; Stop condition
|
|
350 rcall WaitMSSP
|
|
351 return
|
|
352
|
|
353
|
|
354 END |