1 .file "I2C.c" 2 .arch atmega128 3 __SREG__ = 0x3f 4 __SP_H__ = 0x3e 5 __SP_L__ = 0x3d 6 __tmp_reg__ = 0 7 __zero_reg__ = 1 8 .global __do_copy_data 9 .global __do_clear_bss 12 .text 13 .Ltext0: 75 .global i2c_init 77 i2c_init: 1:I2C.c **** // 2:I2C.c **** // Module Name: I2C.c 3:I2C.c **** // 4:I2C.c **** // Description: This module contains the low and high level I2C access routine for the Atmel TWI (I 5:I2C.c **** // 6:I2C.c **** // History: 7:I2C.c **** // - Created on May 1st 2002 by Stephane Gauthier (email: stephane.gauthier@alcatel.com URL:http:// 8:I2C.c **** // - May 21st 2002 - S. Gauthier - Modified i2c_readbyte() and i2c_writebyte() to exit cleanly (run 9:I2C.c **** // - June 2nd 2002 - S. Gauthier - Cleaned up and added I2C error count var for troubleshooting. 10:I2C.c **** // - June 25th 2002 - S. Gauthier - Added _SFR_ASM_COMPAT define to prevent warnings with new AVRG 11:I2C.c **** // 12:I2C.c **** 13:I2C.c **** 14:I2C.c **** #include // For I/O macros 15:I2C.c **** #include // AVRGCC TWI include. 16:I2C.c **** #include "I2C.h" // For our own routines 17:I2C.c **** #include "avrx.h" // For semaphores 18:I2C.c **** #include "generalio.h" // for PrintString 19:I2C.c **** #include "serialio.h" // For error reporting. (PutChar()) 20:I2C.c **** #include "hardware.h" // sets up hardware specifics defines, macros and constants. 21:I2C.c **** 22:I2C.c **** #define I2C_ERROR 1 23:I2C.c **** 24:I2C.c **** unsigned int i2c_errors; 25:I2C.c **** unsigned int i2c_requests; 26:I2C.c **** 27:I2C.c **** // Globals 28:I2C.c **** AVRX_MUTEX(I2C_Mutex); // For controlling access to I2C hardware. 29:I2C.c **** 30:I2C.c **** 31:I2C.c **** // ************************** 32:I2C.c **** // Low-level I2C routines. 33:I2C.c **** // ************************** 34:I2C.c **** 35:I2C.c **** // Function Name: i2c_init() 36:I2C.c **** // 37:I2C.c **** // Description: Initializes the I2C hardware 38:I2C.c **** // 39:I2C.c **** // 40:I2C.c **** void i2c_init(void) 41:I2C.c **** { 79 .LM1: 80 /* prologue: frame size=0 */ 81 /* prologue end (size=0) */ 42:I2C.c **** // Prime I2C semaphore 43:I2C.c **** AvrXSetSemaphore(&I2C_Mutex); 83 .LM2: 84 0000 80E0 ldi r24,lo8(I2C_Mutex) 85 0002 90E0 ldi r25,hi8(I2C_Mutex) 86 0004 0E94 0000 call AvrXSetSemaphore 44:I2C.c **** 45:I2C.c **** // Configure Bit rate generator for 100Khz 46:I2C.c **** TWBR = TWBR_INIT; 88 .LM3: 89 0008 88E4 ldi r24,lo8(72) 90 000a 8093 7000 sts 112,r24 47:I2C.c **** 48:I2C.c **** // Prescaler of 1 49:I2C.c **** TWSR = TWPS_INIT; 92 .LM4: 93 000e 1092 7100 sts 113,__zero_reg__ 50:I2C.c **** 51:I2C.c **** // Enable TWI 52:I2C.c **** TWCR = TWCR_INIT; 95 .LM5: 96 0012 84E0 ldi r24,lo8(4) 97 0014 8093 7400 sts 116,r24 53:I2C.c **** } 99 .LM6: 100 /* epilogue: frame size=0 */ 101 0018 0895 ret 102 /* epilogue end (size=1) */ 103 /* function i2c_init size 13 (12) */ 105 .Lscope0: 109 .global i2c_start 111 i2c_start: 54:I2C.c **** 55:I2C.c **** // Function Name: i2c_start() 56:I2C.c **** // 57:I2C.c **** // Description: Prepare to take over bus. Return 0 if successfull, otherwise 1. 58:I2C.c **** // 59:I2C.c **** // 60:I2C.c **** unsigned char i2c_start(unsigned char data) 61:I2C.c **** { 113 .LM7: 114 /* prologue: frame size=0 */ 115 /* prologue end (size=0) */ 116 001a 282F mov r18,r24 62:I2C.c **** // Initiate Start 63:I2C.c **** outp((BV(TWINT) | BV(TWSTA) | BV(TWEN)), TWCR); 118 .LM8: 119 001c 84EA ldi r24,lo8(-92) 120 001e 8093 7400 sts 116,r24 64:I2C.c **** 65:I2C.c **** // Wait 'till it's done... 66:I2C.c **** while (bit_is_clear(TWCR, TWINT)) 122 .LM9: 123 .L3: 124 0022 8091 7400 lds r24,116 125 0026 87FF sbrs r24,7 126 0028 FCCF rjmp .L3 67:I2C.c **** ; 68:I2C.c **** 69:I2C.c **** // check for proper status in TWSR.. 70:I2C.c **** if ((inp(TWSR) & 0xF8) != TW_START) 128 .LM10: 129 002a 8091 7100 lds r24,113 130 002e 9927 clr r25 131 0030 887F andi r24,lo8(248) 132 0032 9070 andi r25,hi8(248) 133 0034 0897 sbiw r24,8 134 0036 81F4 brne .L11 71:I2C.c **** { 72:I2C.c **** return (1); // BAD!! 136 .LM11: 73:I2C.c **** } 74:I2C.c **** 75:I2C.c **** // Send SLA_W 76:I2C.c **** outp(data, TWDR); 138 .LM12: 139 0038 2093 7300 sts 115,r18 77:I2C.c **** 78:I2C.c **** // start transmission 79:I2C.c **** outp((BV(TWINT) | BV(TWEN)), TWCR); 141 .LM13: 142 003c 84E8 ldi r24,lo8(-124) 143 003e 8093 7400 sts 116,r24 80:I2C.c **** 81:I2C.c **** // Wait 'till it's done... 82:I2C.c **** while (bit_is_clear(TWCR, TWINT)) 145 .LM14: 146 .L7: 147 0042 8091 7400 lds r24,116 148 0046 87FF sbrs r24,7 149 0048 FCCF rjmp .L7 83:I2C.c **** ; 84:I2C.c **** 85:I2C.c **** // check for proper status in TWSR.. 86:I2C.c **** if ((inp(TWSR) & 0xF8) != TW_MT_SLA_ACK) 151 .LM15: 152 004a 8091 7100 lds r24,113 153 004e 9927 clr r25 154 0050 887F andi r24,lo8(248) 155 0052 9070 andi r25,hi8(248) 156 0054 4897 sbiw r24,24 157 0056 19F0 breq .L10 87:I2C.c **** { 88:I2C.c **** return (1); // BAD!! 159 .LM16: 160 .L11: 161 0058 81E0 ldi r24,lo8(1) 162 005a 90E0 ldi r25,hi8(1) 89:I2C.c **** } 90:I2C.c **** 91:I2C.c **** // Success 92:I2C.c **** return (0); 93:I2C.c **** } 164 .LM17: 165 005c 0895 ret 166 .L10: 168 .LM18: 169 005e 80E0 ldi r24,lo8(0) 170 0060 90E0 ldi r25,hi8(0) 172 .LM19: 173 0062 0895 ret 174 /* epilogue: frame size=0 */ 175 0064 0895 ret 176 /* epilogue end (size=1) */ 177 /* function i2c_start size 40 (39) */ 179 .Lscope1: 183 .global i2c_rep_start 185 i2c_rep_start: 94:I2C.c **** 95:I2C.c **** // Function Name: i2c_rep_start() 96:I2C.c **** // 97:I2C.c **** // Description: Repeated Start. Switch mode without losing bus. Return 0 if successfull, otherwis 98:I2C.c **** // 99:I2C.c **** // 100:I2C.c **** unsigned char i2c_rep_start(unsigned char data) 101:I2C.c **** { 187 .LM20: 188 /* prologue: frame size=0 */ 189 /* prologue end (size=0) */ 190 0066 282F mov r18,r24 102:I2C.c **** // Initiate Start 103:I2C.c **** outp((BV(TWINT) | BV(TWSTA) | BV(TWEN)), TWCR); 192 .LM21: 193 0068 84EA ldi r24,lo8(-92) 194 006a 8093 7400 sts 116,r24 104:I2C.c **** 105:I2C.c **** // Wait 'till it's done... 106:I2C.c **** while (bit_is_clear(TWCR, TWINT)) 196 .LM22: 197 .L13: 198 006e 8091 7400 lds r24,116 199 0072 87FF sbrs r24,7 200 0074 FCCF rjmp .L13 107:I2C.c **** ; 108:I2C.c **** 109:I2C.c **** // check for proper status in TWSR.. 110:I2C.c **** if ((inp(TWSR) & 0xF8) != TW_REP_START) 202 .LM23: 203 0076 8091 7100 lds r24,113 204 007a 9927 clr r25 205 007c 887F andi r24,lo8(248) 206 007e 9070 andi r25,hi8(248) 207 0080 4097 sbiw r24,16 208 0082 89F4 brne .L21 111:I2C.c **** { 112:I2C.c **** return (1); // BAD!! 210 .LM24: 113:I2C.c **** } 114:I2C.c **** 115:I2C.c **** // Send SLA_W or SLA_R 116:I2C.c **** outp(data, TWDR); 212 .LM25: 213 0084 2093 7300 sts 115,r18 117:I2C.c **** 118:I2C.c **** // start transmission 119:I2C.c **** outp((BV(TWINT) | BV(TWEN)), TWCR); 215 .LM26: 216 0088 84E8 ldi r24,lo8(-124) 217 008a 8093 7400 sts 116,r24 120:I2C.c **** 121:I2C.c **** // Wait 'till it's done... 122:I2C.c **** while (bit_is_clear(TWCR, TWINT)) 219 .LM27: 220 .L17: 221 008e 8091 7400 lds r24,116 222 0092 87FF sbrs r24,7 223 0094 FCCF rjmp .L17 123:I2C.c **** ; 124:I2C.c **** 125:I2C.c **** // check for proper status in TWSR.. 126:I2C.c **** if ((inp(TWSR) & 0xF8) != TW_MR_SLA_ACK) 225 .LM28: 226 0096 8091 7100 lds r24,113 227 009a 9927 clr r25 228 009c 887F andi r24,lo8(248) 229 009e 9070 andi r25,hi8(248) 230 00a0 8034 cpi r24,64 231 00a2 9105 cpc r25,__zero_reg__ 232 00a4 19F0 breq .L20 127:I2C.c **** { 128:I2C.c **** return (1); // BAD!! 234 .LM29: 235 .L21: 236 00a6 81E0 ldi r24,lo8(1) 237 00a8 90E0 ldi r25,hi8(1) 129:I2C.c **** } 130:I2C.c **** 131:I2C.c **** // Success 132:I2C.c **** return (0); 133:I2C.c **** } 239 .LM30: 240 00aa 0895 ret 241 .L20: 243 .LM31: 244 00ac 80E0 ldi r24,lo8(0) 245 00ae 90E0 ldi r25,hi8(0) 247 .LM32: 248 00b0 0895 ret 249 /* epilogue: frame size=0 */ 250 00b2 0895 ret 251 /* epilogue end (size=1) */ 252 /* function i2c_rep_start size 40 (39) */ 254 .Lscope2: 257 .global i2c_stop 259 i2c_stop: 134:I2C.c **** 135:I2C.c **** // Function Name: i2c_stop() 136:I2C.c **** // 137:I2C.c **** // Description: Release I2C bus. 138:I2C.c **** // 139:I2C.c **** // 140:I2C.c **** void i2c_stop(void) 141:I2C.c **** { 261 .LM33: 262 /* prologue: frame size=0 */ 263 /* prologue end (size=0) */ 142:I2C.c **** // Initiate Stop 143:I2C.c **** outp((BV(TWINT) | BV(TWSTO) | BV(TWEN)), TWCR); 265 .LM34: 266 00b4 84E9 ldi r24,lo8(-108) 267 00b6 8093 7400 sts 116,r24 144:I2C.c **** } 269 .LM35: 270 /* epilogue: frame size=0 */ 271 00ba 0895 ret 272 /* epilogue end (size=1) */ 273 /* function i2c_stop size 4 (3) */ 275 .Lscope3: 279 .global i2c_write 281 i2c_write: 145:I2C.c **** 146:I2C.c **** 147:I2C.c **** // Function Name: i2c_write() 148:I2C.c **** // 149:I2C.c **** // Description: Write byte to currently addressed slave 150:I2C.c **** // 151:I2C.c **** // 152:I2C.c **** unsigned char i2c_write(unsigned char data) 153:I2C.c **** { 283 .LM36: 284 /* prologue: frame size=0 */ 285 /* prologue end (size=0) */ 154:I2C.c **** // Send Data 155:I2C.c **** outp(data, TWDR); // Data 287 .LM37: 288 00bc 8093 7300 sts 115,r24 156:I2C.c **** 157:I2C.c **** // Start transmission 158:I2C.c **** outp((BV(TWINT) | BV(TWEN)), TWCR); 290 .LM38: 291 00c0 84E8 ldi r24,lo8(-124) 292 00c2 8093 7400 sts 116,r24 159:I2C.c **** 160:I2C.c **** // Wait 'till it's done... 161:I2C.c **** while (bit_is_clear(TWCR, TWINT)) 294 .LM39: 295 .L24: 296 00c6 8091 7400 lds r24,116 297 00ca 87FF sbrs r24,7 298 00cc FCCF rjmp .L24 162:I2C.c **** ; 163:I2C.c **** 164:I2C.c **** // check for proper status in TWSR.. 165:I2C.c **** if ((inp(TWSR) & 0xF8) != TW_MT_DATA_ACK) 300 .LM40: 301 00ce 8091 7100 lds r24,113 302 00d2 9927 clr r25 303 00d4 887F andi r24,lo8(248) 304 00d6 9070 andi r25,hi8(248) 305 00d8 8897 sbiw r24,40 306 00da 19F0 breq .L27 166:I2C.c **** { 167:I2C.c **** return (1); // BAD!! 308 .LM41: 309 00dc 81E0 ldi r24,lo8(1) 310 00de 90E0 ldi r25,hi8(1) 168:I2C.c **** } 169:I2C.c **** 170:I2C.c **** // Success 171:I2C.c **** return (0); 172:I2C.c **** } 312 .LM42: 313 00e0 0895 ret 314 .L27: 316 .LM43: 317 00e2 80E0 ldi r24,lo8(0) 318 00e4 90E0 ldi r25,hi8(0) 320 .LM44: 321 00e6 0895 ret 322 /* epilogue: frame size=0 */ 323 00e8 0895 ret 324 /* epilogue end (size=1) */ 325 /* function i2c_write size 24 (23) */ 327 .Lscope4: 331 .global i2c_read 333 i2c_read: 173:I2C.c **** 174:I2C.c **** 175:I2C.c **** // Function Name: i2c_read() 176:I2C.c **** // 177:I2C.c **** // Description: Read byte from currently addressed slave. ack parameter determines if we should s 178:I2C.c **** // 179:I2C.c **** // 180:I2C.c **** unsigned char i2c_read(unsigned char ack) 181:I2C.c **** { 335 .LM45: 336 /* prologue: frame size=0 */ 337 /* prologue end (size=0) */ 182:I2C.c **** // Prepare to receive next byte 183:I2C.c **** if (ack == ACK) 339 .LM46: 340 00ea 8130 cpi r24,lo8(1) 341 00ec 11F4 brne .L29 184:I2C.c **** outp((BV(TWINT) | BV(TWEA) | BV(TWEN)), TWCR); // Send ACK 343 .LM47: 344 00ee 84EC ldi r24,lo8(-60) 345 00f0 01C0 rjmp .L34 346 .L29: 185:I2C.c **** else 186:I2C.c **** outp((BV(TWINT) | BV(TWEN)), TWCR); // Send NACK 348 .LM48: 349 00f2 84E8 ldi r24,lo8(-124) 350 .L34: 351 00f4 8093 7400 sts 116,r24 187:I2C.c **** 188:I2C.c **** // Wait 'till it's done... 189:I2C.c **** while (bit_is_clear(TWCR, TWINT)) 353 .LM49: 354 .L31: 355 00f8 8091 7400 lds r24,116 356 00fc 87FF sbrs r24,7 357 00fe FCCF rjmp .L31 190:I2C.c **** ; 191:I2C.c **** 192:I2C.c **** // Get Data 193:I2C.c **** return(inp(TWDR)); 359 .LM50: 360 0100 8091 7300 lds r24,115 361 0104 9927 clr r25 194:I2C.c **** } 363 .LM51: 364 /* epilogue: frame size=0 */ 365 0106 0895 ret 366 /* epilogue end (size=1) */ 367 /* function i2c_read size 15 (14) */ 369 .Lscope5: 374 .global i2c_readbyte 376 i2c_readbyte: 195:I2C.c **** 196:I2C.c **** // ************************** 197:I2C.c **** // High-level I2C routines. 198:I2C.c **** // ************************** 199:I2C.c **** 200:I2C.c **** 201:I2C.c **** // Function Name: i2c_readbyte() 202:I2C.c **** // 203:I2C.c **** // Description: Read a single byte from device 'i2c_address' at address 'location'. 204:I2C.c **** // 205:I2C.c **** // 206:I2C.c **** unsigned char i2c_readbyte(unsigned char i2c_address, unsigned char location) 207:I2C.c **** { 378 .LM52: 379 /* prologue: frame size=0 */ 380 0108 0F93 push r16 381 010a 1F93 push r17 382 010c CF93 push r28 383 /* prologue end (size=3) */ 384 010e C82F mov r28,r24 385 0110 162F mov r17,r22 208:I2C.c **** unsigned char temp = 0; 387 .LM53: 388 .LBB2: 389 0112 00E0 ldi r16,lo8(0) 209:I2C.c **** 210:I2C.c **** AvrXWaitSemaphore(&I2C_Mutex); 391 .LM54: 392 0114 80E0 ldi r24,lo8(I2C_Mutex) 393 0116 90E0 ldi r25,hi8(I2C_Mutex) 394 0118 0E94 0000 call AvrXWaitSemaphore 211:I2C.c **** 212:I2C.c **** //i2c_requests++; 213:I2C.c **** 214:I2C.c **** // set device address and write mode (exit with error if it fails.) 215:I2C.c **** if (i2c_start(i2c_address+I2C_WRITE)) 396 .LM55: 397 011c 8C2F mov r24,r28 398 011e 0E94 0000 call i2c_start 399 0122 8823 tst r24 400 0124 71F0 breq .L36 216:I2C.c **** { 217:I2C.c **** i2c_errors++; 402 .LM56: 403 0126 8091 0000 lds r24,i2c_errors 404 012a 9091 0000 lds r25,(i2c_errors)+1 405 012e 0196 adiw r24,1 406 0130 9093 0000 sts (i2c_errors)+1,r25 407 0134 8093 0000 sts i2c_errors,r24 218:I2C.c **** 219:I2C.c **** #ifdef I2C_ERROR 220:I2C.c **** PutChar('r'); 409 .LM57: 410 0138 82E7 ldi r24,lo8(114) 411 013a 0E94 0000 call PutChar 221:I2C.c **** PutChar('1'); 413 .LM58: 414 013e 81E3 ldi r24,lo8(49) 415 0140 26C0 rjmp .L42 416 .L36: 222:I2C.c **** #endif 223:I2C.c **** } 224:I2C.c **** else 225:I2C.c **** { 226:I2C.c **** // write byte address 227:I2C.c **** if (i2c_write(location)) 418 .LM59: 419 0142 812F mov r24,r17 420 0144 0E94 0000 call i2c_write 421 0148 8823 tst r24 422 014a 71F0 breq .L38 228:I2C.c **** { 229:I2C.c **** i2c_errors++; 424 .LM60: 425 014c 8091 0000 lds r24,i2c_errors 426 0150 9091 0000 lds r25,(i2c_errors)+1 427 0154 0196 adiw r24,1 428 0156 9093 0000 sts (i2c_errors)+1,r25 429 015a 8093 0000 sts i2c_errors,r24 230:I2C.c **** 231:I2C.c **** #ifdef I2C_ERROR 232:I2C.c **** PutChar('r'); 431 .LM61: 432 015e 82E7 ldi r24,lo8(114) 433 0160 0E94 0000 call PutChar 233:I2C.c **** PutChar('2'); 435 .LM62: 436 0164 82E3 ldi r24,lo8(50) 437 0166 13C0 rjmp .L42 438 .L38: 234:I2C.c **** #endif 235:I2C.c **** } 236:I2C.c **** else 237:I2C.c **** { 238:I2C.c **** // set device address and read mode 239:I2C.c **** if (i2c_rep_start(i2c_address+I2C_READ)) 440 .LM63: 441 0168 CF5F subi r28,lo8(-(1)) 442 016a 8C2F mov r24,r28 443 016c 0E94 0000 call i2c_rep_start 444 0170 8823 tst r24 445 0172 81F0 breq .L40 240:I2C.c **** { 241:I2C.c **** i2c_errors++; 447 .LM64: 448 0174 8091 0000 lds r24,i2c_errors 449 0178 9091 0000 lds r25,(i2c_errors)+1 450 017c 0196 adiw r24,1 451 017e 9093 0000 sts (i2c_errors)+1,r25 452 0182 8093 0000 sts i2c_errors,r24 242:I2C.c **** 243:I2C.c **** #ifdef I2C_ERROR 244:I2C.c **** PutChar('r'); 454 .LM65: 455 0186 82E7 ldi r24,lo8(114) 456 0188 0E94 0000 call PutChar 245:I2C.c **** PutChar('3'); 458 .LM66: 459 018c 83E3 ldi r24,lo8(51) 460 .L42: 461 018e 0E94 0000 call PutChar 462 0192 04C0 rjmp .L37 463 .L40: 246:I2C.c **** #endif 247:I2C.c **** } 248:I2C.c **** else 249:I2C.c **** temp = i2c_read(NACK); // read one byte only 465 .LM67: 466 0194 802F mov r24,r16 467 0196 0E94 0000 call i2c_read 468 019a 082F mov r16,r24 469 .L37: 250:I2C.c **** } 251:I2C.c **** } 252:I2C.c **** 253:I2C.c **** i2c_stop(); 471 .LM68: 472 019c 0E94 0000 call i2c_stop 254:I2C.c **** 255:I2C.c **** AvrXSetSemaphore(&I2C_Mutex); 474 .LM69: 475 01a0 80E0 ldi r24,lo8(I2C_Mutex) 476 01a2 90E0 ldi r25,hi8(I2C_Mutex) 477 01a4 0E94 0000 call AvrXSetSemaphore 256:I2C.c **** 257:I2C.c **** return(temp); 479 .LM70: 480 01a8 802F mov r24,r16 481 01aa 9927 clr r25 258:I2C.c **** } 483 .LM71: 484 .LBE2: 485 /* epilogue: frame size=0 */ 486 01ac CF91 pop r28 487 01ae 1F91 pop r17 488 01b0 0F91 pop r16 489 01b2 0895 ret 490 /* epilogue end (size=4) */ 491 /* function i2c_readbyte size 86 (79) */ 496 .Lscope6: 502 .global i2c_writebyte 504 i2c_writebyte: 259:I2C.c **** 260:I2C.c **** 261:I2C.c **** // Function Name: i2c_writebyte() 262:I2C.c **** // 263:I2C.c **** // Description: Write single byte 'data' to device 'i2c_address' at address 'location'. Returns r 264:I2C.c **** // 265:I2C.c **** // 266:I2C.c **** unsigned char i2c_writebyte(unsigned char i2c_address, unsigned char location, unsigned char data) 267:I2C.c **** { 506 .LM72: 507 /* prologue: frame size=0 */ 508 01b4 FF92 push r15 509 01b6 0F93 push r16 510 01b8 1F93 push r17 511 01ba CF93 push r28 512 /* prologue end (size=4) */ 513 01bc 182F mov r17,r24 514 01be C62F mov r28,r22 515 01c0 042F mov r16,r20 268:I2C.c **** unsigned char temp = 0; 517 .LM73: 518 .LBB3: 519 01c2 FF24 clr r15 269:I2C.c **** 270:I2C.c **** AvrXWaitSemaphore(&I2C_Mutex); 521 .LM74: 522 01c4 80E0 ldi r24,lo8(I2C_Mutex) 523 01c6 90E0 ldi r25,hi8(I2C_Mutex) 524 01c8 0E94 0000 call AvrXWaitSemaphore 271:I2C.c **** 272:I2C.c **** //i2c_requests++; 273:I2C.c **** 274:I2C.c **** // set device address and write mode 275:I2C.c **** if (i2c_start(i2c_address+I2C_WRITE)) 526 .LM75: 527 01cc 812F mov r24,r17 528 01ce 0E94 0000 call i2c_start 529 01d2 8823 tst r24 530 01d4 71F0 breq .L44 276:I2C.c **** { 277:I2C.c **** i2c_errors++; 532 .LM76: 533 01d6 8091 0000 lds r24,i2c_errors 534 01da 9091 0000 lds r25,(i2c_errors)+1 535 01de 0196 adiw r24,1 536 01e0 9093 0000 sts (i2c_errors)+1,r25 537 01e4 8093 0000 sts i2c_errors,r24 278:I2C.c **** 279:I2C.c **** #ifdef I2C_ERROR 280:I2C.c **** PutChar('w'); 539 .LM77: 540 01e8 87E7 ldi r24,lo8(119) 541 01ea 0E94 0000 call PutChar 281:I2C.c **** PutChar('1'); 543 .LM78: 544 01ee 81E3 ldi r24,lo8(49) 545 01f0 26C0 rjmp .L49 546 .L44: 282:I2C.c **** #endif 283:I2C.c **** } 284:I2C.c **** else 285:I2C.c **** { 286:I2C.c **** if (i2c_write(location)) // write location address to write to 548 .LM79: 549 01f2 8C2F mov r24,r28 550 01f4 0E94 0000 call i2c_write 551 01f8 8823 tst r24 552 01fa 71F0 breq .L46 287:I2C.c **** { 288:I2C.c **** i2c_errors++; 554 .LM80: 555 01fc 8091 0000 lds r24,i2c_errors 556 0200 9091 0000 lds r25,(i2c_errors)+1 557 0204 0196 adiw r24,1 558 0206 9093 0000 sts (i2c_errors)+1,r25 559 020a 8093 0000 sts i2c_errors,r24 289:I2C.c **** 290:I2C.c **** #ifdef I2C_ERROR 291:I2C.c **** PutChar('w'); 561 .LM81: 562 020e 87E7 ldi r24,lo8(119) 563 0210 0E94 0000 call PutChar 292:I2C.c **** PutChar('2'); 565 .LM82: 566 0214 82E3 ldi r24,lo8(50) 567 0216 13C0 rjmp .L49 568 .L46: 293:I2C.c **** #endif 294:I2C.c **** } 295:I2C.c **** else 296:I2C.c **** { 297:I2C.c **** if ((temp = i2c_write(data))) // ret=0 -> Ok, ret=1 -> no ACK 570 .LM83: 571 0218 802F mov r24,r16 572 021a 0E94 0000 call i2c_write 573 021e F82E mov r15,r24 574 0220 8823 tst r24 575 0222 79F0 breq .L45 298:I2C.c **** { 299:I2C.c **** i2c_errors++; 577 .LM84: 578 0224 8091 0000 lds r24,i2c_errors 579 0228 9091 0000 lds r25,(i2c_errors)+1 580 022c 0196 adiw r24,1 581 022e 9093 0000 sts (i2c_errors)+1,r25 582 0232 8093 0000 sts i2c_errors,r24 300:I2C.c **** 301:I2C.c **** #ifdef I2C_ERROR 302:I2C.c **** PutChar('w'); 584 .LM85: 585 0236 87E7 ldi r24,lo8(119) 586 0238 0E94 0000 call PutChar 303:I2C.c **** PutChar('3'); 588 .LM86: 589 023c 83E3 ldi r24,lo8(51) 590 .L49: 591 023e 0E94 0000 call PutChar 592 .L45: 304:I2C.c **** #endif 305:I2C.c **** } 306:I2C.c **** } 307:I2C.c **** } 308:I2C.c **** 309:I2C.c **** i2c_stop(); // set stop conditon = release bus 594 .LM87: 595 0242 0E94 0000 call i2c_stop 310:I2C.c **** 311:I2C.c **** AvrXSetSemaphore(&I2C_Mutex); 597 .LM88: 598 0246 80E0 ldi r24,lo8(I2C_Mutex) 599 0248 90E0 ldi r25,hi8(I2C_Mutex) 600 024a 0E94 0000 call AvrXSetSemaphore 312:I2C.c **** 313:I2C.c **** return(temp); 602 .LM89: 603 024e 8F2D mov r24,r15 604 0250 9927 clr r25 314:I2C.c **** } 606 .LM90: 607 .LBE3: 608 /* epilogue: frame size=0 */ 609 0252 CF91 pop r28 610 0254 1F91 pop r17 611 0256 0F91 pop r16 612 0258 FF90 pop r15 613 025a 0895 ret 614 /* epilogue end (size=5) */ 615 /* function i2c_writebyte size 84 (75) */ 620 .Lscope7: 625 .global i2c_readword 627 i2c_readword: 315:I2C.c **** 316:I2C.c **** 317:I2C.c **** // Function Name: i2c_readword() 318:I2C.c **** // 319:I2C.c **** // Description: Read a single word from device 'i2c_address' at address 'location'. 320:I2C.c **** // 321:I2C.c **** // 322:I2C.c **** unsigned int i2c_readword(unsigned char i2c_address, unsigned char location) 323:I2C.c **** { 629 .LM91: 630 /* prologue: frame size=0 */ 631 025c FF92 push r15 632 025e 0F93 push r16 633 0260 1F93 push r17 634 0262 CF93 push r28 635 /* prologue end (size=4) */ 636 0264 C82F mov r28,r24 637 0266 F62E mov r15,r22 324:I2C.c **** 325:I2C.c **** unsigned int temp = 0; 639 .LM92: 640 .LBB4: 641 0268 00E0 ldi r16,lo8(0) 642 026a 10E0 ldi r17,hi8(0) 326:I2C.c **** 327:I2C.c **** AvrXWaitSemaphore(&I2C_Mutex); 644 .LM93: 645 026c 80E0 ldi r24,lo8(I2C_Mutex) 646 026e 90E0 ldi r25,hi8(I2C_Mutex) 647 0270 0E94 0000 call AvrXWaitSemaphore 328:I2C.c **** 329:I2C.c **** if (i2c_start(i2c_address+I2C_WRITE)) // set device address and write mode 649 .LM94: 650 0274 8C2F mov r24,r28 651 0276 0E94 0000 call i2c_start 652 027a 8823 tst r24 653 027c 61F4 brne .L57 330:I2C.c **** { 331:I2C.c **** i2c_errors++; 332:I2C.c **** } 333:I2C.c **** else 334:I2C.c **** { 335:I2C.c **** if (i2c_write(location)) // write byte address 655 .LM95: 656 027e 8F2D mov r24,r15 657 0280 0E94 0000 call i2c_write 658 0284 8823 tst r24 659 0286 39F4 brne .L57 336:I2C.c **** { 337:I2C.c **** i2c_errors++; 338:I2C.c **** } 339:I2C.c **** else 340:I2C.c **** { 341:I2C.c **** if (i2c_rep_start(i2c_address+I2C_READ)) // set device address and read mode 661 .LM96: 662 0288 CF5F subi r28,lo8(-(1)) 663 028a 8C2F mov r24,r28 664 028c 0E94 0000 call i2c_rep_start 665 0290 C82F mov r28,r24 666 0292 8823 tst r24 667 0294 51F0 breq .L55 342:I2C.c **** { 343:I2C.c **** i2c_errors++; 669 .LM97: 670 .L57: 671 0296 8091 0000 lds r24,i2c_errors 672 029a 9091 0000 lds r25,(i2c_errors)+1 673 029e 0196 adiw r24,1 674 02a0 9093 0000 sts (i2c_errors)+1,r25 675 02a4 8093 0000 sts i2c_errors,r24 676 02a8 0BC0 rjmp .L52 677 .L55: 344:I2C.c **** } 345:I2C.c **** else 346:I2C.c **** { 347:I2C.c **** temp = i2c_read(ACK) << 8; // Get High Byte 679 .LM98: 680 02aa 81E0 ldi r24,lo8(1) 681 02ac 0E94 0000 call i2c_read 682 02b0 9927 clr r25 683 02b2 182F mov r17,r24 684 02b4 0027 clr r16 348:I2C.c **** temp += i2c_read(NACK); // Get Low Byte 686 .LM99: 687 02b6 8C2F mov r24,r28 688 02b8 0E94 0000 call i2c_read 689 02bc 080F add r16,r24 690 02be 111D adc r17,__zero_reg__ 691 .L52: 349:I2C.c **** } 350:I2C.c **** } 351:I2C.c **** } 352:I2C.c **** 353:I2C.c **** i2c_stop(); 693 .LM100: 694 02c0 0E94 0000 call i2c_stop 354:I2C.c **** 355:I2C.c **** AvrXSetSemaphore(&I2C_Mutex); 696 .LM101: 697 02c4 80E0 ldi r24,lo8(I2C_Mutex) 698 02c6 90E0 ldi r25,hi8(I2C_Mutex) 699 02c8 0E94 0000 call AvrXSetSemaphore 356:I2C.c **** 357:I2C.c **** return(temp); 358:I2C.c **** } 701 .LM102: 702 .LBE4: 703 02cc C801 movw r24,r16 704 /* epilogue: frame size=0 */ 705 02ce CF91 pop r28 706 02d0 1F91 pop r17 707 02d2 0F91 pop r16 708 02d4 FF90 pop r15 709 02d6 0895 ret 710 /* epilogue end (size=5) */ 711 /* function i2c_readword size 62 (53) */ 716 .Lscope8: 722 .global i2c_writeword 724 i2c_writeword: 359:I2C.c **** 360:I2C.c **** 361:I2C.c **** // Function Name: i2c_writeword() 362:I2C.c **** // 363:I2C.c **** // Description: Write single word 'data' to device 'i2c_address' at address 'location'. Returns r 364:I2C.c **** // 365:I2C.c **** // 366:I2C.c **** unsigned char i2c_writeword(unsigned char i2c_address, unsigned char location, unsigned int data) 367:I2C.c **** { 726 .LM103: 727 /* prologue: frame size=0 */ 728 02d8 FF92 push r15 729 02da 0F93 push r16 730 02dc 1F93 push r17 731 02de CF93 push r28 732 02e0 DF93 push r29 733 /* prologue end (size=5) */ 734 02e2 182F mov r17,r24 735 02e4 062F mov r16,r22 736 02e6 EA01 movw r28,r20 368:I2C.c **** 369:I2C.c **** unsigned char temp=0; 738 .LM104: 739 .LBB5: 740 02e8 FF24 clr r15 370:I2C.c **** 371:I2C.c **** AvrXWaitSemaphore(&I2C_Mutex); 742 .LM105: 743 02ea 80E0 ldi r24,lo8(I2C_Mutex) 744 02ec 90E0 ldi r25,hi8(I2C_Mutex) 745 02ee 0E94 0000 call AvrXWaitSemaphore 372:I2C.c **** 373:I2C.c **** if (i2c_start(i2c_address+I2C_WRITE)) // set device address and write mode 747 .LM106: 748 02f2 812F mov r24,r17 749 02f4 0E94 0000 call i2c_start 750 02f8 8823 tst r24 751 02fa 91F4 brne .L66 374:I2C.c **** { 375:I2C.c **** i2c_errors++; 376:I2C.c **** } 377:I2C.c **** else 378:I2C.c **** { 379:I2C.c **** if (i2c_write(location)) // write location address to write to 753 .LM107: 754 02fc 802F mov r24,r16 755 02fe 0E94 0000 call i2c_write 756 0302 8823 tst r24 757 0304 69F4 brne .L66 380:I2C.c **** { 381:I2C.c **** i2c_errors++; 382:I2C.c **** } 383:I2C.c **** else 384:I2C.c **** { 385:I2C.c **** if ((temp = i2c_write((unsigned char)(data >> 8)))) // Write High Byte first 759 .LM108: 760 0306 8D2F mov r24,r29 761 0308 9927 clr r25 762 030a 0E94 0000 call i2c_write 763 030e F82E mov r15,r24 764 0310 8823 tst r24 765 0312 31F4 brne .L66 386:I2C.c **** { 387:I2C.c **** i2c_errors++; 388:I2C.c **** } 389:I2C.c **** else 390:I2C.c **** { 391:I2C.c **** if (temp += i2c_write((unsigned char)data)) // Write Low Byte 767 .LM109: 768 0314 8C2F mov r24,r28 769 0316 0E94 0000 call i2c_write 770 031a F82E mov r15,r24 771 031c 8823 tst r24 772 031e 49F0 breq .L60 392:I2C.c **** { 393:I2C.c **** i2c_errors++; 774 .LM110: 775 .L66: 776 0320 8091 0000 lds r24,i2c_errors 777 0324 9091 0000 lds r25,(i2c_errors)+1 778 0328 0196 adiw r24,1 779 032a 9093 0000 sts (i2c_errors)+1,r25 780 032e 8093 0000 sts i2c_errors,r24 781 .L60: 394:I2C.c **** } 395:I2C.c **** } 396:I2C.c **** } 397:I2C.c **** } 398:I2C.c **** 399:I2C.c **** i2c_stop(); // set stop conditon = release bus 783 .LM111: 784 0332 0E94 0000 call i2c_stop 400:I2C.c **** 401:I2C.c **** AvrXSetSemaphore(&I2C_Mutex); 786 .LM112: 787 0336 80E0 ldi r24,lo8(I2C_Mutex) 788 0338 90E0 ldi r25,hi8(I2C_Mutex) 789 033a 0E94 0000 call AvrXSetSemaphore 402:I2C.c **** 403:I2C.c **** return(temp); 791 .LM113: 792 033e 8F2D mov r24,r15 793 0340 9927 clr r25 404:I2C.c **** } 795 .LM114: 796 .LBE5: 797 /* epilogue: frame size=0 */ 798 0342 DF91 pop r29 799 0344 CF91 pop r28 800 0346 1F91 pop r17 801 0348 0F91 pop r16 802 034a FF90 pop r15 803 034c 0895 ret 804 /* epilogue end (size=6) */ 805 /* function i2c_writeword size 59 (48) */ 810 .Lscope9: 812 .comm i2c_errors,2,1 813 .comm i2c_requests,2,1 814 .comm I2C_Mutex,2,1 818 .text 820 Letext: 821 /* File "I2C.c": code 427 = 0x01ab ( 385), prologues 16, epilogues 26 */ DEFINED SYMBOLS *ABS*:00000000 I2C.c *ABS*:0000003f __SREG__ *ABS*:0000003e __SP_H__ *ABS*:0000003d __SP_L__ *ABS*:00000000 __tmp_reg__ *ABS*:00000001 __zero_reg__ C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:77 .text:00000000 i2c_init *COM*:00000002 I2C_Mutex C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:111 .text:0000001a i2c_start C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:185 .text:00000066 i2c_rep_start C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:259 .text:000000b4 i2c_stop C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:281 .text:000000bc i2c_write C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:333 .text:000000ea i2c_read C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:376 .text:00000108 i2c_readbyte *COM*:00000002 i2c_errors C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:504 .text:000001b4 i2c_writebyte C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:627 .text:0000025c i2c_readword C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:724 .text:000002d8 i2c_writeword *COM*:00000002 i2c_requests C:\DOCUME~1\palm3\LOCALS~1\Temp/ccS6aaaa.s:820 .text:0000034e Letext *ABS*:00000000 *ABS* UNDEFINED SYMBOLS __do_copy_data __do_clear_bss AvrXSetSemaphore AvrXWaitSemaphore PutChar