comparison src/i2c.asm @ 0:11d4fc797f74

init
author heinrichsweikamp
date Wed, 24 Apr 2013 19:22:45 +0200
parents
children 4e3f133dfbf4
comparison
equal deleted inserted replaced
-1:000000000000 0:11d4fc797f74
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