Mercurial > public > hwos_code
annotate src/i2c.asm @ 223:940155e9aefb
PC config, 1.72 release
| author | heinrichsweikamp |
|---|---|
| date | Wed, 14 Jan 2015 11:37:19 +0100 |
| parents | 4147cd5c0c8e |
| children | 23311219dacc |
| 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" | |
| 113 | 21 #include "math.inc" |
| 22 | |
| 200 | 23 #DEFINE battery_offset .29065 ; 65536-(3,1Ah/0,085mAh) |
| 24 #DEFINE battery_devider .365 ; 3,1Ah/0,085mAh/100 [%] | |
| 0 | 25 |
| 26 i2c CODE | |
| 27 | |
| 28 WaitMSSP: | |
| 29 decfsz i2c_temp,F ; check for timeout during I2C action | |
| 30 bra WaitMSSP2 | |
| 31 bra I2CFail ; timeout occured | |
| 32 WaitMSSP2: | |
| 33 btfss PIR1,SSPIF | |
| 34 bra WaitMSSP | |
| 35 clrf i2c_temp | |
| 36 bcf PIR1,SSPIF | |
| 37 nop | |
| 38 return | |
| 39 | |
| 40 I2C_WaitforACK: | |
| 41 btfss SSPCON2,ACKSTAT ; checks for ACK bit from slave | |
| 42 return | |
| 43 I2CFail: | |
| 44 rcall I2CReset ; I2C Reset | |
| 45 bcf PIR1,SSPIF | |
| 46 clrf i2c_temp | |
| 47 return | |
| 48 | |
| 49 I2CReset: ; Something went wrong (Slave holds SDA low?) | |
| 50 clrf SSP1CON1 ; wake-up slave and reset entire module | |
| 51 clrf SSP1CON2 | |
| 52 clrf SSP1STAT | |
| 53 bcf TRISC,3 ; SCL OUTPUT | |
| 54 bsf TRISC,4 ; SDA Input | |
| 55 bcf PORTC,3 | |
| 56 movlw d'9' | |
| 57 movwf i2c_temp ; clock-out 9 clock cycles manually | |
| 58 I2CReset_1: | |
| 59 bsf PORTC,3 ; SCL=1 | |
| 60 nop | |
| 61 nop | |
| 62 nop | |
| 63 nop | |
| 64 btfsc PORTC,4 ; SDA=1? | |
| 65 bra I2CReset_2 ; =1, SDA has been released from slave | |
| 66 bcf PORTC,3 ; SCL=0 | |
| 67 nop | |
| 68 nop | |
| 69 bcf PORTC,3 | |
| 70 nop | |
| 71 nop | |
| 72 decfsz i2c_temp,F | |
| 73 bra I2CReset_1 ; check for nine clock cycles | |
| 74 I2CReset_2: | |
| 75 bsf TRISC,3 ; SCL Input | |
| 76 clrf SSP1CON1 ; setup I²C Mode | |
| 77 WAITMS d'10' ; Reset-Timeout for I2C devices | |
| 78 movlw b'00000000' ; with slew rate control | |
| 79 movwf SSPSTAT | |
| 80 movlw b'00101000' | |
| 81 movwf SSP1CON1 | |
| 82 movlw b'00000000' | |
| 83 movwf SSP1CON2 | |
| 84 movlw 0x27 | |
| 85 movwf SSP1ADD | |
| 86 return | |
| 87 | |
| 88 I2C_TX: | |
| 89 movwf SSP1BUF | |
| 90 rcall WaitMSSP | |
| 91 bra I2C_WaitforACK ; Returns... | |
| 92 | |
| 93 I2C_TwoBytesRX_div16: ; Get two bytes and devide lo:hi/16 (signed) | |
| 94 rcall I2C_OneByteRX ; Get one byte | |
| 95 movff SSP1BUF,hi ; Data Byte | |
| 96 rcall I2C_OneByteRX ; Get one byte | |
| 97 movff SSP1BUF,lo ; Data Byte | |
| 98 I2C_TwoBytesRX_div16_2: ; devide lo:hi/16 (signed) only | |
| 99 bcf STATUS,C | |
| 100 btfsc hi,7 ; Copy sign bit to carry | |
| 101 bsf STATUS,C | |
| 102 rrcf hi ; /2 | |
| 103 rrcf lo | |
| 104 bcf STATUS,C | |
| 105 btfsc hi,7 ; Copy sign bit to carry | |
| 106 bsf STATUS,C | |
| 107 rrcf hi ; /4 | |
| 108 rrcf lo | |
| 109 bcf STATUS,C | |
| 110 btfsc hi,7 ; Copy sign bit to carry | |
| 111 bsf STATUS,C | |
| 112 rrcf hi ; /8 | |
| 113 rrcf lo | |
| 114 bcf STATUS,C | |
| 115 btfsc hi,7 ; Copy sign bit to carry | |
| 116 bsf STATUS,C | |
| 117 rrcf hi ; /16 | |
| 118 rrcf lo | |
| 119 return | |
| 120 | |
| 121 global I2C_RX_accelerometer | |
| 122 I2C_RX_accelerometer: | |
| 123 bsf SSP1CON2,SEN ; Start condition | |
| 124 rcall WaitMSSP | |
| 125 movlw 0x38 ; address | |
| 126 rcall I2C_TX | |
| 158 | 127 movlw 0x00 |
| 0 | 128 rcall I2C_TX |
| 129 bsf SSP1CON2,RSEN ; Repeated start condition (!) | |
| 130 rcall WaitMSSP | |
| 131 movlw 0x39 ; address | |
| 132 rcall I2C_TX | |
| 133 | |
| 158 | 134 rcall I2C_OneByteRX ; Get Status Byte |
| 135 movf SSP1BUF,W | |
| 136 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
137 ; Non-flipped screen: |
| 0 | 138 ; Chip orientation on the PCB requires |
| 139 ; Original = Corrected | |
| 140 ; x = -x | |
| 141 ; y = -y | |
| 142 ; z = -z | |
| 143 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
144 ; Flipped screen: |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
145 ; Chip orientation on the PCB requires |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
146 ; Original = Corrected |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
147 ; x = x |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
148 ; y = y |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
149 ; z = -z |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
150 |
| 0 | 151 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed) |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
152 btfsc flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
153 bra I2C_RX_accelerometer2 ; Yes |
| 0 | 154 comf hi ; 16bit sign change. |
| 155 negf lo | |
| 156 btfsc STATUS,C ; Carry to propagate ? | |
| 157 incf hi,F ; YES: do it. | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
158 I2C_RX_accelerometer2: |
| 0 | 159 movff lo,accel_DX+0 |
| 160 movff hi,accel_DX+1 ; Copy result | |
| 161 | |
| 162 rcall I2C_TwoBytesRX_div16 ; Get two bytes and devide /16 (signed) | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
163 btfsc flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
164 bra I2C_RX_accelerometer3 ; Yes |
| 0 | 165 comf hi ; 16bit sign change. |
| 166 negf lo | |
| 167 btfsc STATUS,C ; Carry to propagate ? | |
| 168 incf hi,F ; YES: do it. | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
169 I2C_RX_accelerometer3: |
| 0 | 170 movff lo,accel_DY+0 |
| 171 movff hi,accel_DY+1 ; Copy result | |
| 172 | |
| 173 rcall I2C_OneByteRX ; Get one byte | |
| 174 movff SSP1BUF,hi ; Data Byte | |
| 175 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 176 rcall WaitMSSP | |
| 177 ; According to datasheet there should be no Master Acknowlegde for the last Byte (accel_DZ+0)... | |
| 178 movff SSP1BUF,lo ; Data Byte | |
| 179 | |
| 180 rcall I2C_TwoBytesRX_div16_2; devide lo:hi/16 (signed) only | |
| 181 comf hi ; 16bit sign change. | |
| 182 negf lo | |
| 183 btfsc STATUS,C ; Carry to propagate ? | |
| 184 incf hi,F ; YES: do it. | |
| 185 movff lo,accel_DZ+0 | |
| 186 movff hi,accel_DZ+1 ; Copy result | |
| 187 | |
| 188 bsf SSP1CON2,PEN ; Stop condition | |
| 189 rcall WaitMSSP | |
| 190 return | |
| 191 | |
| 192 I2C_OneByteRX: | |
| 193 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 194 rcall WaitMSSP | |
| 195 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 196 rcall WaitMSSP | |
| 197 return | |
| 198 | |
| 199 global I2C_RX_compass | |
| 200 I2C_RX_compass: | |
| 201 bsf SSP1CON2,SEN ; Start condition | |
| 202 rcall WaitMSSP | |
| 203 movlw 0x3C ; address | |
| 204 rcall I2C_TX | |
| 205 movlw 0x03 | |
| 206 rcall I2C_TX | |
| 207 bsf SSP1CON2,PEN ; Stop condition | |
| 208 rcall WaitMSSP | |
| 209 | |
| 210 bcf PIR1,SSPIF | |
| 211 bsf SSP1CON2,SEN ; Start condition | |
| 212 rcall WaitMSSP | |
| 213 movlw 0x3D ; address | |
| 214 rcall I2C_TX | |
| 215 | |
| 216 ; Compass IC sends data in following order: | |
| 217 ; x MSB | |
| 218 ; x LSB | |
| 219 ; z MSB | |
| 220 ; z LSB | |
| 221 ; y MSB | |
| 222 ; y LSB | |
| 223 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
224 ; Non-flipped screen |
| 0 | 225 ; Chip orientation on the PCB requires |
| 226 ; Original = Corrected | |
| 227 ; x = -y | |
| 228 ; z = z | |
| 229 ; y = x | |
| 230 | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
231 ; Flipped screen |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
232 ; Chip orientation on the PCB requires |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
233 ; Original = Corrected |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
234 ; x = y |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
235 ; z = z |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
236 ; y = -x |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
237 |
| 0 | 238 rcall I2C_OneByteRX ; Get one byte |
| 239 movff SSP1BUF,compass_DY+1; Data Byte | |
| 240 rcall I2C_OneByteRX ; Get one byte | |
| 241 movff SSP1BUF,compass_DY+0; Data Byte | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
242 btfsc flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
243 bra I2C_RX_compass2 ; Yes |
| 0 | 244 banksel compass_DY |
| 245 comf compass_DY+1 ; 16bit sign change. | |
| 246 negf compass_DY+0 | |
| 247 btfsc STATUS,C ; Carry to propagate ? | |
| 248 incf compass_DY+1,F ; YES: do it. | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
249 I2C_RX_compass2: |
| 0 | 250 banksel common |
| 251 rcall I2C_OneByteRX ; Get one byte | |
| 252 movff SSP1BUF,compass_DZ+1; Data Byte | |
| 253 rcall I2C_OneByteRX ; Get one byte | |
| 254 movff SSP1BUF,compass_DZ+0; Data Byte | |
| 255 rcall I2C_OneByteRX ; Get one byte | |
| 256 movff SSP1BUF,compass_DX+1; Data Byte | |
| 257 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 258 rcall WaitMSSP | |
| 259 movff SSP1BUF,compass_DX+0; Data Byte | |
| 260 bsf SSP1CON2,PEN ; Stop condition | |
| 261 rcall WaitMSSP | |
|
166
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
262 btfss flip_screen ; 180° rotation ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
263 return ; No, done. |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
264 ; Yes, flip X |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
265 banksel compass_DX |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
266 comf compass_DX+1 ; 16bit sign change. |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
267 negf compass_DX+0 |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
268 btfsc STATUS,C ; Carry to propagate ? |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
269 incf compass_DX+1,F ; YES: do it. |
|
30ebaf72170d
BUGFIX: Flip compass with flipped screen, too
heinrichsweikamp
parents:
158
diff
changeset
|
270 banksel common |
| 0 | 271 return |
| 272 | |
| 273 global I2C_init_compass | |
| 274 I2C_init_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'01101001' ; ConfigA: 3Hz, 8 Samples averaged, Test Mode (Positive Bias) | |
| 282 movlw b'01101000' ; ConfigA: 3Hz, 8 Samples averaged | |
| 283 rcall I2C_TX | |
| 20 | 284 bra I2C_init_compass_common |
| 285 | |
| 286 global I2C_init_compass_fast | |
| 287 I2C_init_compass_fast: | |
| 288 bsf SSP1CON2,SEN ; Start condition | |
| 289 rcall WaitMSSP | |
| 290 movlw 0x3C ; address | |
| 291 rcall I2C_TX | |
| 292 movlw 0x00 | |
| 293 rcall I2C_TX | |
| 294 movlw b'00111000' ; ConfigA: 75Hz, 2 Samples averaged | |
| 295 ; movlw b'00111001' ; ConfigA: 75Hz, 2 Samples averaged, Test Mode (Positive Bias) | |
| 296 rcall I2C_TX | |
| 297 I2C_init_compass_common: | |
|
18
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
298 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
|
299 swapf i2c_temp,F |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
300 comf i2c_temp,F |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
301 bcf STATUS,C |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
302 rlcf i2c_temp |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
303 movf i2c_temp,W |
|
4e3f133dfbf4
add new opt_compass_gain option to work with more magnetic battery types
heinrichsweikamp
parents:
0
diff
changeset
|
304 clrf i2c_temp |
| 0 | 305 rcall I2C_TX |
| 306 movlw b'00000000' ; Continous Mode | |
| 307 rcall I2C_TX | |
| 308 bsf SSP1CON2,PEN ; Stop condition | |
| 309 rcall WaitMSSP | |
| 310 bsf compass_enabled | |
| 311 return | |
| 312 | |
| 313 global I2C_sleep_compass | |
| 314 I2C_sleep_compass: | |
| 315 bsf SSP1CON2,SEN ; Start condition | |
| 316 rcall WaitMSSP | |
| 317 movlw 0x3C ; address | |
| 318 rcall I2C_TX | |
| 319 movlw 0x00 | |
| 320 rcall I2C_TX | |
| 321 movlw b'01101000' ; ConfigA | |
| 322 rcall I2C_TX | |
| 323 movlw b'00100000' ; ConfigB | |
| 324 rcall I2C_TX | |
| 325 movlw b'00000010' ; Idle Mode | |
| 326 rcall I2C_TX | |
| 327 bsf SSP1CON2,PEN ; Stop condition | |
| 328 rcall WaitMSSP | |
| 329 bcf compass_enabled | |
| 330 return | |
| 331 | |
| 332 | |
| 333 global I2C_init_accelerometer | |
| 334 I2C_init_accelerometer: | |
| 335 rcall I2C_sleep_accelerometer ; Regs can only be changed in St.By mode | |
| 336 | |
| 337 bsf SSP1CON2,SEN ; Start condition | |
| 338 rcall WaitMSSP | |
| 339 movlw 0x38 ; address | |
| 340 rcall I2C_TX | |
| 341 movlw 0x0E ; XYZ_DATA_CFG | |
| 342 rcall I2C_TX | |
| 343 movlw b'00000000' ; High pass Filter=0 , +/- 2g range | |
| 344 rcall I2C_TX | |
| 345 bsf SSP1CON2,PEN ; Stop condition | |
| 346 rcall WaitMSSP | |
| 347 | |
| 348 | |
| 349 bsf SSP1CON2,SEN ; Start condition | |
| 350 rcall WaitMSSP | |
| 351 movlw 0x38 ; address | |
| 352 rcall I2C_TX | |
| 353 movlw 0x2A ; CTRL_REG1 | |
| 354 rcall I2C_TX | |
| 355 ; movlw b'00110000' ; CTRL_REG1: 160ms data rate, St.By Mode | |
| 356 movlw b'00110100' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode | |
| 357 rcall I2C_TX | |
| 358 movlw b'00000010' ; CTRL_REG2: High Res in Active mode | |
| 359 rcall I2C_TX | |
| 360 bsf SSP1CON2,PEN ; Stop condition | |
| 361 rcall WaitMSSP | |
| 362 | |
| 363 bsf SSP1CON2,SEN ; Start condition | |
| 364 rcall WaitMSSP | |
| 365 movlw 0x38 ; address | |
| 366 rcall I2C_TX | |
| 367 movlw 0x2A ; CTRL_REG1 | |
| 368 rcall I2C_TX | |
| 369 ; movlw b'00110001' ; CTRL_REG1: 160ms data rate, Active Mode | |
| 370 movlw b'00110101' ; CTRL_REG1: 160ms data rate, St.By Mode, reduced noise mode, Active Mode | |
| 371 rcall I2C_TX | |
| 372 bsf SSP1CON2,PEN ; Stop condition | |
| 373 rcall WaitMSSP | |
| 374 | |
| 375 return | |
| 376 | |
| 377 global I2C_sleep_accelerometer | |
| 378 I2C_sleep_accelerometer: | |
| 379 bsf SSP1CON2,SEN ; Start condition | |
| 380 rcall WaitMSSP | |
| 381 movlw 0x38 ; address | |
| 382 rcall I2C_TX | |
| 383 movlw 0x2A ; CTRL_REG1 | |
| 384 rcall I2C_TX | |
| 385 movlw b'00000000' ; St. By Mode | |
| 386 rcall I2C_TX | |
| 387 bsf SSP1CON2,PEN ; Stop condition | |
| 388 rcall WaitMSSP | |
| 389 return | |
| 390 | |
| 113 | 391 global lt2942_init |
| 392 lt2942_init: ; Setup Control register B | |
| 393 clrf i2c_temp | |
| 394 movlw 0x01 ; Point to control reg B | |
| 395 call I2C_TX_GAUGE | |
| 396 movlw b'11111000' ; Automatic conversion every two seconds | |
| 397 movff WREG, SSP1BUF ; Data Byte | |
| 398 rcall WaitMSSP | |
| 399 rcall I2C_WaitforACK | |
| 400 bsf SSP1CON2,PEN ; Stop condition | |
| 401 rcall WaitMSSP | |
| 402 return | |
| 403 | |
| 404 global lt2942_get_status | |
| 405 lt2942_get_status: ; Read status register | |
| 200 | 406 bcf cr_hardware ; Clear flag |
| 113 | 407 clrf i2c_temp |
| 408 movlw 0x00 ; Point to Status reg | |
| 409 call I2C_TX_GAUGE | |
| 410 call I2C_RX_GAUGE | |
| 411 movff SSP1BUF,WREG | |
| 412 btfss WREG,7 ; 2942 found? | |
| 200 | 413 bsf cr_hardware ; Yes, set flag |
| 113 | 414 bsf SSP1CON2,PEN ; Stop condition |
| 415 rcall WaitMSSP | |
| 416 return | |
| 417 | |
| 418 | |
| 419 global lt2942_get_voltage | |
| 420 lt2942_get_voltage: ; Read battery voltage registers | |
| 421 clrf i2c_temp | |
| 422 movlw 0x08 ; Point to voltage registers | |
| 423 call I2C_TX_GAUGE | |
| 424 call I2C_RX_GAUGE | |
| 425 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 426 rcall WaitMSSP | |
| 427 movff SSP1BUF,xA+1 | |
| 428 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 429 rcall WaitMSSP | |
| 430 movff SSP1BUF,xA+0 | |
| 431 bsf SSP1CON2,PEN ; Stop condition | |
| 432 rcall WaitMSSP | |
| 433 | |
| 434 ; banksel common | |
| 435 ; xA:2 loaded with raw values | |
| 436 movlw LOW .6000 | |
| 437 movwf xB+0 | |
| 438 movlw HIGH .6000 | |
| 439 movwf xB+1 | |
| 440 call mult16x16 ;xA*xB=xC | |
| 441 | |
| 442 ; devide xC (32bit)/65535 for result in mV (16bit) | |
| 443 movlw .16 | |
| 444 movwf i2c_temp | |
| 445 lt2942_get_voltage2: | |
| 446 bcf STATUS,C | |
| 447 rrcf xC+3,F | |
| 448 rrcf xC+2,F | |
| 449 rrcf xC+1,F | |
| 450 rrcf xC+0,F | |
| 451 decfsz i2c_temp,F | |
| 452 bra lt2942_get_voltage2 | |
| 453 | |
| 454 ; Update battery voltage in mV | |
| 455 movff xC+1,batt_voltage+1 | |
| 456 movff xC+0,batt_voltage+0 | |
| 457 return | |
| 458 | |
| 459 ; global lt2942_get_temperature | |
| 460 ;lt2942_get_temperature: ; Read temperature registers | |
| 461 ; clrf i2c_temp | |
| 462 ; movlw 0x0C ; Point to temperature registers | |
| 463 ; call I2C_TX_GAUGE | |
| 464 ; call I2C_RX | |
| 465 ; bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 466 ; rcall WaitMSSP | |
| 467 ; movff SSP1BUF,xA+1 | |
| 468 ; bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 469 ; rcall WaitMSSP | |
| 470 ; movff SSP1BUF,xA+0 | |
| 471 ; bsf SSP1CON2,PEN ; Stop condition | |
| 472 ; rcall WaitMSSP | |
| 473 ; | |
| 474 ;; banksel common | |
| 475 ; ; xA:2 loaded with raw values | |
| 476 ; movlw LOW .6000 | |
| 477 ; movwf xB+0 | |
| 478 ; movlw HIGH .6000 | |
| 479 ; movwf xB+1 | |
| 480 ; call mult16x16 ;xA*xB=xC | |
| 481 ; | |
| 482 ; ; devide xC (32bit)/65535 for result in 0.1K (16bit) | |
| 483 ; movlw .16 | |
| 484 ; movwf i2c_temp | |
| 485 ;lt2942_get_temperature2: | |
| 486 ; bcf STATUS,C | |
| 487 ; rrcf xC+3,F | |
| 488 ; rrcf xC+2,F | |
| 489 ; rrcf xC+1,F | |
| 490 ; rrcf xC+0,F | |
| 491 ; decfsz i2c_temp,F | |
| 492 ; bra lt2942_get_temperature2 | |
| 493 ; | |
| 494 ; movff xC+1,sub_a+1 | |
| 495 ; movff xC+0,sub_a+0 | |
| 496 ; movlw LOW .2731 ; Kelvin to Celcius offset | |
| 497 ; movwf sub_b+0 | |
| 498 ; movlw HIGH .2731 ; Kelvin to Celcius offset | |
| 499 ; movwf sub_b+1 | |
| 500 ; call subU16 ; sub_c = sub_a - sub_b (with UNSIGNED values) | |
| 501 ; | |
| 502 ; ; Update batttery_temperature in 0.1°C | |
| 503 ; movff sub_c+1,battery_temperature+1 | |
| 504 ; movff sub_c+0,battery_temperature+0 | |
| 505 ; return | |
| 506 | |
| 507 global lt2942_get_accumulated_charge | |
| 508 lt2942_get_accumulated_charge: ; Read accumulated charge and compute percent | |
| 509 clrf i2c_temp | |
| 510 movlw 0x02 ; Point to accumulated charge registers | |
| 511 call I2C_TX_GAUGE | |
| 512 call I2C_RX_GAUGE | |
| 513 bsf SSP1CON2,ACKEN ; Master acknowlegde | |
| 514 rcall WaitMSSP | |
| 515 movff SSP1BUF,sub_a+1 ; battery_acumulated_charge+1 | |
| 516 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 517 rcall WaitMSSP | |
| 518 movff SSP1BUF,sub_a+0 ; battery_acumulated_charge+0 | |
| 519 bsf SSP1CON2,PEN ; Stop condition | |
| 520 rcall WaitMSSP | |
| 521 | |
| 522 ; Compute batt_percent | |
| 211 | 523 ; (charge-battery_offset)/365 |
| 113 | 524 movlw LOW battery_offset |
| 525 movwf sub_b+0 | |
| 526 movlw HIGH battery_offset | |
| 527 movwf sub_b+1 | |
| 528 call subU16 ; sub_c = sub_a - sub_b (with signed values) | |
| 529 | |
| 530 clrf batt_percent ; Set to zero | |
| 531 btfsc neg_flag ; result negative? | |
| 532 return ; Yes, done. | |
| 533 | |
| 534 ; > Zero, set batt_percent properly | |
| 535 movff sub_c+0,xA+0 | |
| 536 movff sub_c+1,xA+1 | |
| 537 movlw LOW battery_devider | |
| 538 movwf xB+0 | |
| 539 movlw HIGH battery_devider | |
| 540 movwf xB+1 | |
| 541 call div16x16 ;xA/xB=xC with xA+0 as remainder, uses divB as temp variable | |
| 542 movff xC+0,batt_percent | |
| 543 return | |
| 544 | |
| 545 global lt2942_charge_done | |
| 546 lt2942_charge_done: ; Reset accumulating registers to 0xFFFF | |
| 547 clrf i2c_temp | |
| 548 movlw 0x02 ; Point to accumulated charge registers | |
| 549 call I2C_TX_GAUGE | |
| 550 movlw 0xFF | |
| 551 movff WREG, SSP1BUF ; Data Byte | |
| 552 rcall WaitMSSP | |
| 553 rcall I2C_WaitforACK | |
| 554 movlw 0xFF | |
| 555 movff WREG, SSP1BUF ; Data Byte | |
| 556 rcall WaitMSSP | |
| 557 rcall I2C_WaitforACK | |
| 558 bsf SSP1CON2,PEN ; Stop condition | |
| 559 rcall WaitMSSP | |
| 560 return | |
| 561 | |
| 562 I2C_TX_GAUGE: ; Sends a byte to the LT2942 Gauge IC | |
| 563 movwf i2c_temp+1 ; Data byte | |
| 564 bsf SSP1CON2,SEN ; Start condition | |
| 565 rcall WaitMSSP | |
| 566 movlw b'11001000' ; Address byte + Write bit | |
| 567 movwf SSP1BUF ; control byte | |
| 568 rcall WaitMSSP | |
| 569 rcall I2C_WaitforACK | |
| 570 movff i2c_temp+1, SSP1BUF ; Data Byte | |
| 571 rcall WaitMSSP | |
| 572 rcall I2C_WaitforACK | |
| 573 return | |
| 574 | |
| 575 I2C_RX_GAUGE: | |
| 576 bsf SSP1CON2,SEN ; Start condition | |
| 577 rcall WaitMSSP | |
| 578 movlw b'11001001' ; Address byte + Read bit | |
| 579 movwf SSP1BUF ; control byte | |
| 580 rcall WaitMSSP | |
| 581 rcall I2C_WaitforACK | |
| 582 bsf SSP1CON2, RCEN ; Enable recieve mode | |
| 583 rcall WaitMSSP | |
| 584 return | |
| 585 | |
| 586 | |
| 0 | 587 |
| 588 END |
