Mercurial > public > hwos_code
annotate src/i2c.asm @ 85:45a420beb534
No graphical output (yet)
author | heinrichsweikamp |
---|---|
date | Mon, 31 Mar 2014 14:16:17 +0200 |
parents | 9b7dd3103545 |
children | f3062a611eef |
rev | line source |
---|---|
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 rcall I2C_TX | |
20 | 244 bra I2C_init_compass_common |
245 | |
246 global I2C_init_compass_fast | |
247 I2C_init_compass_fast: | |
248 bsf SSP1CON2,SEN ; Start condition | |
249 rcall WaitMSSP | |
250 movlw 0x3C ; address | |
251 rcall I2C_TX | |
252 movlw 0x00 | |
253 rcall I2C_TX | |
254 movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged | |
255 ; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) | |
256 rcall I2C_TX | |
257 I2C_init_compass_common: | |
18
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
258 movff opt_compass_gain,i2c_temp ; 0-7 (230LSB/Gauss to 1370LSB/Gaus) |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
259 swapf i2c_temp,F |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
260 comf i2c_temp,F |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
261 bcf STATUS,C |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
262 rlcf i2c_temp |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
263 movf i2c_temp,W |
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
264 clrf i2c_temp |
0 | 265 rcall I2C_TX |
266 movlw b'00000000' ; Continous Mode | |
267 rcall I2C_TX | |
268 bsf SSP1CON2,PEN ; Stop condition | |
269 rcall WaitMSSP | |
270 bsf compass_enabled | |
271 return | |
272 | |
273 global I2C_sleep_compass | |
274 I2C_sleep_compass: | |
275 bsf SSP1CON2,SEN ; Start condition | |
276 rcall WaitMSSP | |
277 movlw 0x3C ; address | |
278 rcall I2C_TX | |
279 movlw 0x00 | |
280 rcall I2C_TX | |
281 movlw b'01101000' ; ConfigA | |
282 rcall I2C_TX | |
283 movlw b'00100000' ; ConfigB | |
284 rcall I2C_TX | |
285 movlw b'00000010' ; Idle Mode | |
286 rcall I2C_TX | |
287 bsf SSP1CON2,PEN ; Stop condition | |
288 rcall WaitMSSP | |
289 bcf compass_enabled | |
290 return | |
291 | |
292 | |
293 global I2C_init_accelerometer | |
294 I2C_init_accelerometer: | |
295 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode | |
296 | |
297 bsf SSP1CON2,SEN ; Start condition | |
298 rcall WaitMSSP | |
299 movlw 0x38 ; address | |
300 rcall I2C_TX | |
301 movlw 0x0E ; XYZ_DATA_CFG | |
302 rcall I2C_TX | |
303 movlw b'00000000' ; High pass Filter=0 , +/- 2g range | |
304 rcall I2C_TX | |
305 bsf SSP1CON2,PEN ; Stop condition | |
306 rcall WaitMSSP | |
307 | |
308 | |
309 bsf SSP1CON2,SEN ; Start condition | |
310 rcall WaitMSSP | |
311 movlw 0x38 ; address | |
312 rcall I2C_TX | |
313 movlw 0x2A ; CTRL_REG1 | |
314 rcall I2C_TX | |
315 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode | |
316 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode | |
317 rcall I2C_TX | |
318 movlw b'00000010' ; CTRL_REG2: High Res in Active mode | |
319 rcall I2C_TX | |
320 bsf SSP1CON2,PEN ; Stop condition | |
321 rcall WaitMSSP | |
322 | |
323 bsf SSP1CON2,SEN ; Start condition | |
324 rcall WaitMSSP | |
325 movlw 0x38 ; address | |
326 rcall I2C_TX | |
327 movlw 0x2A ; CTRL_REG1 | |
328 rcall I2C_TX | |
329 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode | |
330 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode | |
331 rcall I2C_TX | |
332 bsf SSP1CON2,PEN ; Stop condition | |
333 rcall WaitMSSP | |
334 | |
335 return | |
336 | |
337 global I2C_sleep_accelerometer | |
338 I2C_sleep_accelerometer: | |
339 bsf SSP1CON2,SEN ; Start condition | |
340 rcall WaitMSSP | |
341 movlw 0x38 ; address | |
342 rcall I2C_TX | |
343 movlw 0x2A ; CTRL_REG1 | |
344 rcall I2C_TX | |
345 movlw b'00000000' ; St. By Mode | |
346 rcall I2C_TX | |
347 bsf SSP1CON2,PEN ; Stop condition | |
348 rcall WaitMSSP | |
349 return | |
350 | |
351 | |
352 END |