?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file i2c.c \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */
2 //*****************************************************************************
3 //
4 // File Name : 'i2c.c'
5 // Title : I2C interface using AVR Two-Wire Interface (TWI) hardware
6 // Author : Pascal Stang - Copyright (C) 2002-2003
7 // Created : 2002.06.25
8 // Revised : 2003.03.02
9 // Version : 0.9
10 // Target MCU : Atmel AVR series
11 // Editor Tabs : 4
12 //
13 // This code is distributed under the GNU Public License
14 // which can be found at http://www.gnu.org/licenses/gpl.txt
15 //
16 //*****************************************************************************
17  
18 #include <avr/io.h>
19 #include <avr/interrupt.h>
20  
21 #include "i2c.h"
22  
23 #include "rprintf.h" // include printf function library
24 #include "uart2.h"
25  
26 // Standard I2C bit rates are:
27 // 100KHz for slow speed
28 // 400KHz for high speed
29  
30 //#define I2C_DEBUG
31  
32 // I2C state and address variables
33 static volatile eI2cStateType I2cState;
34 static u08 I2cDeviceAddrRW;
35 // send/transmit buffer (outgoing data)
36 static u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
37 static u08 I2cSendDataIndex;
38 static u08 I2cSendDataLength;
39 // receive buffer (incoming data)
40 static u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
41 static u08 I2cReceiveDataIndex;
42 static u08 I2cReceiveDataLength;
43  
44 // function pointer to i2c receive routine
45 //! I2cSlaveReceive is called when this processor
46 // is addressed as a slave for writing
47 static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);
48 //! I2cSlaveTransmit is called when this processor
49 // is addressed as a slave for reading
50 static u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData);
51  
52 // functions
53 void i2cInit(void)
54 {
55 // set pull-up resistors on I2C bus pins
56 // TODO: should #ifdef these
57 sbi(PORTC, 0); // i2c SCL on ATmega163,323,16,32,etc
58 sbi(PORTC, 1); // i2c SDA on ATmega163,323,16,32,etc
59 sbi(PORTD, 0); // i2c SCL on ATmega128,64
60 sbi(PORTD, 1); // i2c SDA on ATmega128,64
61  
62 // clear SlaveReceive and SlaveTransmit handler to null
63 i2cSlaveReceive = 0;
64 i2cSlaveTransmit = 0;
65 // set i2c bit rate to 100KHz
66 i2cSetBitrate(100);
67 // enable TWI (two-wire interface)
68 sbi(TWCR, TWEN);
69 // set state
70 I2cState = I2C_IDLE;
71 // enable TWI interrupt and slave address ACK
72 sbi(TWCR, TWIE);
73 sbi(TWCR, TWEA);
74 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
75 // enable interrupts
76 sei();
77 }
78  
79 void i2cSetBitrate(u16 bitrateKHz)
80 {
81 u08 bitrate_div;
82 // set i2c bitrate
83 // SCL freq = F_CPU/(16+2*TWBR))
84 #ifdef TWPS0
85 // for processors with additional bitrate division (mega128)
86 // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
87 // set TWPS to zero
88 cbi(TWSR, TWPS0);
89 cbi(TWSR, TWPS1);
90 #endif
91 // calculate bitrate division
92 bitrate_div = ((F_CPU/1000l)/bitrateKHz);
93 if(bitrate_div >= 16)
94 bitrate_div = (bitrate_div-16)/2;
95 outb(TWBR, bitrate_div);
96 }
97  
98 void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
99 {
100 // set local device address (used in slave mode only)
101 outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
102 }
103  
104 void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData))
105 {
106 i2cSlaveReceive = i2cSlaveRx_func;
107 }
108  
109 void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData))
110 {
111 i2cSlaveTransmit = i2cSlaveTx_func;
112 }
113  
114 inline void i2cSendStart(void)
115 {
116 // send start condition
117 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
118 }
119  
120 inline void i2cSendStop(void)
121 {
122 // transmit stop condition
123 // leave with TWEA on for slave receiving
124 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
125 }
126  
127 inline void i2cWaitForComplete(void)
128 {
129 // wait for i2c interface to complete operation
130 while( !(inb(TWCR) & BV(TWINT)) );
131 }
132  
133 inline void i2cSendByte(u08 data)
134 {
135 // save data to the TWDR
136 outb(TWDR, data);
137 // begin send
138 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
139 }
140  
141 inline void i2cReceiveByte(u08 ackFlag)
142 {
143 // begin receive over i2c
144 if( ackFlag )
145 {
146 // ackFlag = TRUE: ACK the recevied data
147 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
148 }
149 else
150 {
151 // ackFlag = FALSE: NACK the recevied data
152 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
153 }
154 }
155  
156 inline u08 i2cGetReceivedByte(void)
157 {
158 // retieve received data byte from i2c TWDR
159 return( inb(TWDR) );
160 }
161  
162 inline u08 i2cGetStatus(void)
163 {
164 // retieve current i2c status from i2c TWSR
165 return( inb(TWSR) );
166 }
167  
168 void i2cMasterSend(u08 deviceAddr, u08 length, u08* data)
169 {
170 u08 i;
171 // wait for interface to be ready
172 while(I2cState);
173 // set state
174 I2cState = I2C_MASTER_TX;
175 // save data
176 I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW cleared: write operation
177 for(i=0; i<length; i++)
178 I2cSendData[i] = *data++;
179 I2cSendDataIndex = 0;
180 I2cSendDataLength = length;
181 // send start condition
182 i2cSendStart();
183 }
184  
185 void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data)
186 {
187 u08 i;
188 // wait for interface to be ready
189 while(I2cState);
190 // set state
191 I2cState = I2C_MASTER_RX;
192 // save data
193 I2cDeviceAddrRW = (deviceAddr|0x01); // RW set: read operation
194 I2cReceiveDataIndex = 0;
195 I2cReceiveDataLength = length;
196 // send start condition
197 i2cSendStart();
198 // wait for data
199 while(I2cState);
200 // return data
201 for(i=0; i<length; i++)
202 *data++ = I2cReceiveData[i];
203 }
204  
205 u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
206 {
207 u08 retval = I2C_OK;
208  
209 // disable TWI interrupt
210 cbi(TWCR, TWIE);
211  
212 // send start condition
213 i2cSendStart();
214 i2cWaitForComplete();
215  
216 // send device address with write
217 i2cSendByte( deviceAddr & 0xFE );
218 i2cWaitForComplete();
219  
220 // check if device is present and live
221 if( inb(TWSR) == TW_MT_SLA_ACK)
222 {
223 // send data
224 while(length)
225 {
226 i2cSendByte( *data++ );
227 i2cWaitForComplete();
228 length--;
229 }
230 }
231 else
232 {
233 // device did not ACK it's address,
234 // data will not be transferred
235 // return error
236 retval = I2C_ERROR_NODEV;
237 }
238  
239 // transmit stop condition
240 // leave with TWEA on for slave receiving
241 i2cSendStop();
242 while( !(inb(TWCR) & BV(TWSTO)) );
243  
244 // enable TWI interrupt
245 sbi(TWCR, TWIE);
246  
247 return retval;
248 }
249  
250 u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
251 {
252 u08 retval = I2C_OK;
253  
254 // disable TWI interrupt
255 cbi(TWCR, TWIE);
256  
257 // send start condition
258 i2cSendStart();
259 i2cWaitForComplete();
260  
261 // send device address with read
262 i2cSendByte( deviceAddr | 0x01 );
263 i2cWaitForComplete();
264  
265 // check if device is present and live
266 if( inb(TWSR) == TW_MR_SLA_ACK)
267 {
268 // accept receive data and ack it
269 while(length > 1)
270 {
271 i2cReceiveByte(TRUE);
272 i2cWaitForComplete();
273 *data++ = i2cGetReceivedByte();
274 // decrement length
275 length--;
276 }
277  
278 // accept receive data and nack it (last-byte signal)
279 i2cReceiveByte(FALSE);
280 i2cWaitForComplete();
281 *data++ = i2cGetReceivedByte();
282 }
283 else
284 {
285 // device did not ACK it's address,
286 // data will not be transferred
287 // return error
288 retval = I2C_ERROR_NODEV;
289 }
290  
291 // transmit stop condition
292 // leave with TWEA on for slave receiving
293 i2cSendStop();
294  
295 // enable TWI interrupt
296 sbi(TWCR, TWIE);
297  
298 return retval;
299 }
300 /*
301 void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata)
302 {
303 // disable TWI interrupt
304 cbi(TWCR, TWIE);
305  
306 // send start condition
307 i2cSendStart();
308 i2cWaitForComplete();
309  
310 // if there's data to be sent, do it
311 if(sendlength)
312 {
313 // send device address with write
314 i2cSendByte( deviceAddr & 0xFE );
315 i2cWaitForComplete();
316  
317 // send data
318 while(sendlength)
319 {
320 i2cSendByte( *senddata++ );
321 i2cWaitForComplete();
322 sendlength--;
323 }
324 }
325  
326 // if there's data to be received, do it
327 if(receivelength)
328 {
329 // send repeated start condition
330 i2cSendStart();
331 i2cWaitForComplete();
332  
333 // send device address with read
334 i2cSendByte( deviceAddr | 0x01 );
335 i2cWaitForComplete();
336  
337 // accept receive data and ack it
338 while(receivelength > 1)
339 {
340 i2cReceiveByte(TRUE);
341 i2cWaitForComplete();
342 *receivedata++ = i2cGetReceivedByte();
343 // decrement length
344 receivelength--;
345 }
346  
347 // accept receive data and nack it (last-byte signal)
348 i2cReceiveByte(TRUE);
349 i2cWaitForComplete();
350 *receivedata++ = i2cGetReceivedByte();
351 }
352  
353 // transmit stop condition
354 // leave with TWEA on for slave receiving
355 i2cSendStop();
356 while( !(inb(TWCR) & BV(TWSTO)) );
357  
358 // enable TWI interrupt
359 sbi(TWCR, TWIE);
360 }
361 */
362  
363 //! I2C (TWI) interrupt service routine
364 SIGNAL(SIG_2WIRE_SERIAL)
365 {
366 // read status bits
367 u08 status = inb(TWSR) & TWSR_STATUS_MASK;
368  
369 switch(status)
370 {
371 // Master General
372 case TW_START: // 0x08: Sent start condition
373 case TW_REP_START: // 0x10: Sent repeated start condition
374 #ifdef I2C_DEBUG
375 rprintfInit(uart1AddToTxBuffer);
376 rprintf("I2C: M->START\r\n");
377 rprintfInit(uart1SendByte);
378 #endif
379 // send device address
380 i2cSendByte(I2cDeviceAddrRW);
381 break;
382  
383 // Master Transmitter & Receiver status codes
384 case TW_MT_SLA_ACK: // 0x18: Slave address acknowledged
385 case TW_MT_DATA_ACK: // 0x28: Data acknowledged
386 #ifdef I2C_DEBUG
387 rprintfInit(uart1AddToTxBuffer);
388 rprintf("I2C: MT->SLA_ACK or DATA_ACK\r\n");
389 rprintfInit(uart1SendByte);
390 #endif
391 if(I2cSendDataIndex < I2cSendDataLength)
392 {
393 // send data
394 i2cSendByte( I2cSendData[I2cSendDataIndex++] );
395 }
396 else
397 {
398 // transmit stop condition, enable SLA ACK
399 i2cSendStop();
400 // set state
401 I2cState = I2C_IDLE;
402 }
403 break;
404 case TW_MR_DATA_NACK: // 0x58: Data received, NACK reply issued
405 #ifdef I2C_DEBUG
406 rprintfInit(uart1AddToTxBuffer);
407 rprintf("I2C: MR->DATA_NACK\r\n");
408 rprintfInit(uart1SendByte);
409 #endif
410 // store final received data byte
411 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
412 // continue to transmit STOP condition
413 case TW_MR_SLA_NACK: // 0x48: Slave address not acknowledged
414 case TW_MT_SLA_NACK: // 0x20: Slave address not acknowledged
415 case TW_MT_DATA_NACK: // 0x30: Data not acknowledged
416 #ifdef I2C_DEBUG
417 rprintfInit(uart1AddToTxBuffer);
418 rprintf("I2C: MTR->SLA_NACK or MT->DATA_NACK\r\n");
419 rprintfInit(uart1SendByte);
420 #endif
421 // transmit stop condition, enable SLA ACK
422 i2cSendStop();
423 // set state
424 I2cState = I2C_IDLE;
425 break;
426 case TW_MT_ARB_LOST: // 0x38: Bus arbitration lost
427 //case TW_MR_ARB_LOST: // 0x38: Bus arbitration lost
428 #ifdef I2C_DEBUG
429 rprintfInit(uart1AddToTxBuffer);
430 rprintf("I2C: MT->ARB_LOST\r\n");
431 rprintfInit(uart1SendByte);
432 #endif
433 // release bus
434 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
435 // set state
436 I2cState = I2C_IDLE;
437 // release bus and transmit start when bus is free
438 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
439 break;
440 case TW_MR_DATA_ACK: // 0x50: Data acknowledged
441 #ifdef I2C_DEBUG
442 rprintfInit(uart1AddToTxBuffer);
443 rprintf("I2C: MR->DATA_ACK\r\n");
444 rprintfInit(uart1SendByte);
445 #endif
446 // store received data byte
447 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
448 // fall-through to see if more bytes will be received
449 case TW_MR_SLA_ACK: // 0x40: Slave address acknowledged
450 #ifdef I2C_DEBUG
451 rprintfInit(uart1AddToTxBuffer);
452 rprintf("I2C: MR->SLA_ACK\r\n");
453 rprintfInit(uart1SendByte);
454 #endif
455 if(I2cReceiveDataIndex < (I2cReceiveDataLength-1))
456 // data byte will be received, reply with ACK (more bytes in transfer)
457 i2cReceiveByte(TRUE);
458 else
459 // data byte will be received, reply with NACK (final byte in transfer)
460 i2cReceiveByte(FALSE);
461 break;
462  
463 // Slave Receiver status codes
464 case TW_SR_SLA_ACK: // 0x60: own SLA+W has been received, ACK has been returned
465 case TW_SR_ARB_LOST_SLA_ACK: // 0x68: own SLA+W has been received, ACK has been returned
466 case TW_SR_GCALL_ACK: // 0x70: GCA+W has been received, ACK has been returned
467 case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: GCA+W has been received, ACK has been returned
468 #ifdef I2C_DEBUG
469 rprintfInit(uart1AddToTxBuffer);
470 rprintf("I2C: SR->SLA_ACK\r\n");
471 rprintfInit(uart1SendByte);
472 #endif
473 // we are being addressed as slave for writing (data will be received from master)
474 // set state
475 I2cState = I2C_SLAVE_RX;
476 // prepare buffer
477 I2cReceiveDataIndex = 0;
478 // receive data byte and return ACK
479 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
480 break;
481 case TW_SR_DATA_ACK: // 0x80: data byte has been received, ACK has been returned
482 case TW_SR_GCALL_DATA_ACK: // 0x90: data byte has been received, ACK has been returned
483 #ifdef I2C_DEBUG
484 rprintfInit(uart1AddToTxBuffer);
485 rprintf("I2C: SR->DATA_ACK\r\n");
486 rprintfInit(uart1SendByte);
487 #endif
488 // get previously received data byte
489 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
490 // check receive buffer status
491 if(I2cReceiveDataIndex < I2C_RECEIVE_DATA_BUFFER_SIZE)
492 {
493 // receive data byte and return ACK
494 i2cReceiveByte(TRUE);
495 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
496 }
497 else
498 {
499 // receive data byte and return NACK
500 i2cReceiveByte(FALSE);
501 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
502 }
503 break;
504 case TW_SR_DATA_NACK: // 0x88: data byte has been received, NACK has been returned
505 case TW_SR_GCALL_DATA_NACK: // 0x98: data byte has been received, NACK has been returned
506 #ifdef I2C_DEBUG
507 rprintfInit(uart1AddToTxBuffer);
508 rprintf("I2C: SR->DATA_NACK\r\n");
509 rprintfInit(uart1SendByte);
510 #endif
511 // receive data byte and return NACK
512 i2cReceiveByte(FALSE);
513 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
514 break;
515 case TW_SR_STOP: // 0xA0: STOP or REPEATED START has been received while addressed as slave
516 #ifdef I2C_DEBUG
517 rprintfInit(uart1AddToTxBuffer);
518 rprintf("I2C: SR->SR_STOP\r\n");
519 rprintfInit(uart1SendByte);
520 #endif
521 // switch to SR mode with SLA ACK
522 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
523 // i2c receive is complete, call i2cSlaveReceive
524 if(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData);
525 // set state
526 I2cState = I2C_IDLE;
527 break;
528  
529 // Slave Transmitter
530 case TW_ST_SLA_ACK: // 0xA8: own SLA+R has been received, ACK has been returned
531 case TW_ST_ARB_LOST_SLA_ACK: // 0xB0: GCA+R has been received, ACK has been returned
532 #ifdef I2C_DEBUG
533 rprintfInit(uart1AddToTxBuffer);
534 rprintf("I2C: ST->SLA_ACK\r\n");
535 rprintfInit(uart1SendByte);
536 #endif
537 // we are being addressed as slave for reading (data must be transmitted back to master)
538 // set state
539 I2cState = I2C_SLAVE_TX;
540 // request data from application
541 if(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData);
542 // reset data index
543 I2cSendDataIndex = 0;
544 // fall-through to transmit first data byte
545 case TW_ST_DATA_ACK: // 0xB8: data byte has been transmitted, ACK has been received
546 #ifdef I2C_DEBUG
547 rprintfInit(uart1AddToTxBuffer);
548 rprintf("I2C: ST->DATA_ACK\r\n");
549 rprintfInit(uart1SendByte);
550 #endif
551 // transmit data byte
552 outb(TWDR, I2cSendData[I2cSendDataIndex++]);
553 if(I2cSendDataIndex < I2cSendDataLength)
554 // expect ACK to data byte
555 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
556 else
557 // expect NACK to data byte
558 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
559 break;
560 case TW_ST_DATA_NACK: // 0xC0: data byte has been transmitted, NACK has been received
561 case TW_ST_LAST_DATA: // 0xC8:
562 #ifdef I2C_DEBUG
563 rprintfInit(uart1AddToTxBuffer);
564 rprintf("I2C: ST->DATA_NACK or LAST_DATA\r\n");
565 rprintfInit(uart1SendByte);
566 #endif
567 // all done
568 // switch to open slave
569 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
570 // set state
571 I2cState = I2C_IDLE;
572 break;
573  
574 // Misc
575 case TW_NO_INFO: // 0xF8: No relevant state information
576 // do nothing
577 #ifdef I2C_DEBUG
578 rprintfInit(uart1AddToTxBuffer);
579 rprintf("I2C: NO_INFO\r\n");
580 rprintfInit(uart1SendByte);
581 #endif
582 break;
583 case TW_BUS_ERROR: // 0x00: Bus error due to illegal start or stop condition
584 #ifdef I2C_DEBUG
585 rprintfInit(uart1AddToTxBuffer);
586 rprintf("I2C: BUS_ERROR\r\n");
587 rprintfInit(uart1SendByte);
588 #endif
589 // reset internal hardware and release bus
590 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
591 // set state
592 I2cState = I2C_IDLE;
593 break;
594 }
595 }
596  
597 eI2cStateType i2cGetState(void)
598 {
599 return I2cState;
600 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3