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