| 359 | kaklik | 1 |   | 
        
           |  |  | 2 | /****************************************************************************
 | 
        
           |  |  | 3 |  Title	:   C  file for the I2C FUNCTIONS library (i2c.c)
 | 
        
           |  |  | 4 |  Author:    Chris efstathiou hendrix@otenet.gr
 | 
        
           |  |  | 5 |  Date:	    13/Jul/2002
 | 
        
           |  |  | 6 |  Software:  AVR-GCC with AVR-AS
 | 
        
           |  |  | 7 |  Target:    any AVR device
 | 
        
           |  |  | 8 |  Comments:  This software is FREE.
 | 
        
           |  |  | 9 |   | 
        
           |  |  | 10 | *****************************************************************************/
 | 
        
           |  |  | 11 |   | 
        
           |  |  | 12 | #include <io.h>
 | 
        
           |  |  | 13 | #include "i2c.h"
 | 
        
           |  |  | 14 |   | 
        
           |  |  | 15 | #ifndef CONCAT1
 | 
        
           |  |  | 16 | #define CONCAT1(a, b) CONCAT2(a, b)
 | 
        
           |  |  | 17 | #endif
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | #ifndef CONCAT2
 | 
        
           |  |  | 20 | #define CONCAT2(a, b) a ## b
 | 
        
           |  |  | 21 | #endif
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 | /* Conversion of microseconds to the right value for the delay function */
 | 
        
           |  |  | 25 | #define I2C_DELAY	   ( (I2C_DELAY_TIME*(F_CPU/60000))/100 )  
 | 
        
           |  |  | 26 | #define I2C_TIMEOUT	   ( (I2C_TIMEOUT_TIME*(F_CPU/60000))/100 ) 
 | 
        
           |  |  | 27 |   | 
        
           |  |  | 28 | /* Register name forming */
 | 
        
           |  |  | 29 | #define I2C_SDA_OUT_REG   CONCAT1(PORT, I2C_SDA_PORT)
 | 
        
           |  |  | 30 | #define I2C_SCL_OUT_REG   CONCAT1(PORT, I2C_SCL_PORT)
 | 
        
           |  |  | 31 | #define I2C_SDA_DDR_REG   CONCAT1(DDR, I2C_SDA_PORT)
 | 
        
           |  |  | 32 | #define I2C_SCL_DDR_REG   CONCAT1(DDR, I2C_SCL_PORT)
 | 
        
           |  |  | 33 | #define I2C_SDA_PIN_REG   CONCAT1(PIN, I2C_SDA_PORT)
 | 
        
           |  |  | 34 | #define I2C_SCL_PIN_REG   CONCAT1(PIN, I2C_SCL_PORT)
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 | /* Conversion of microseconds to the right value for the delay function */
 | 
        
           |  |  | 37 | #define I2C_DELAY	  ( (I2C_DELAY_TIME*(F_CPU/60000))/100 )  
 | 
        
           |  |  | 38 | #define I2C_TIMEOUT	  ( (I2C_TIMEOUT_TIME*(F_CPU/60000))/100 ) 
 | 
        
           |  |  | 39 |   | 
        
           |  |  | 40 | /* Pin states */
 | 
        
           |  |  | 41 | #define SCL_1() 	  cbi(I2C_SCL_DDR_REG, SCL_PIN)
 | 
        
           |  |  | 42 | #define SCL_0() 	  sbi(I2C_SCL_DDR_REG, SCL_PIN)
 | 
        
           |  |  | 43 | #define SDA_1() 	  cbi(I2C_SDA_DDR_REG, SDA_PIN)
 | 
        
           |  |  | 44 | #define SDA_0() 	  sbi(I2C_SDA_DDR_REG, SDA_PIN)
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 | #define RELEASE_I2C_BUS() { SCL_1(); SDA_1(); }
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 | /*#################################################################################################*/
 | 
        
           |  |  | 49 |   | 
        
           |  |  | 50 | static void delay(unsigned long us)
 | 
        
           |  |  | 51 | {
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 |    while ( us ) { us--; }  /* 6 cpu cycles per loop */
 | 
        
           |  |  | 54 |   | 
        
           |  |  | 55 | }
 | 
        
           |  |  | 56 | /*#################################################################################################*/
 | 
        
           |  |  | 57 |   | 
        
           |  |  | 58 | void i2c_init(void)
 | 
        
           |  |  | 59 | {
 | 
        
           |  |  | 60 | 	cbi(I2C_SDA_OUT_REG, SDA_PIN);
 | 
        
           |  |  | 61 | 	cbi(I2C_SCL_OUT_REG, SCL_PIN);
 | 
        
           |  |  | 62 | 	RELEASE_I2C_BUS();
 | 
        
           |  |  | 63 | 	delay(I2C_TIMEOUT);
 | 
        
           |  |  | 64 | 	i2c_start();
 | 
        
           |  |  | 65 | 	delay(I2C_TIMEOUT);
 | 
        
           |  |  | 66 | 	i2c_stop();
 | 
        
           |  |  | 67 | 	delay(I2C_TIMEOUT);
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 | return;
 | 
        
           |  |  | 71 | }
 | 
        
           |  |  | 72 | /*#################################################################################################*/
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 | void i2c_start(void)
 | 
        
           |  |  | 75 | {
 | 
        
           |  |  | 76 | 	RELEASE_I2C_BUS();
 | 
        
           |  |  | 77 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 78 | 	SDA_0();
 | 
        
           |  |  | 79 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 80 | 	SCL_0();
 | 
        
           |  |  | 81 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 | return;
 | 
        
           |  |  | 84 | }
 | 
        
           |  |  | 85 | /*#################################################################################################*/
 | 
        
           |  |  | 86 |   | 
        
           |  |  | 87 | void i2c_stop(void)
 | 
        
           |  |  | 88 | {
 | 
        
           |  |  | 89 | 	SDA_0();
 | 
        
           |  |  | 90 | 	SCL_1();
 | 
        
           |  |  | 91 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 92 | 	SDA_1();
 | 
        
           |  |  | 93 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 94 | 	SCL_0();
 | 
        
           |  |  | 95 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 | return;
 | 
        
           |  |  | 98 | }
 | 
        
           |  |  | 99 | /*#################################################################################################*/
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 101 | unsigned char i2c_transmit(unsigned char data)
 | 
        
           |  |  | 102 | {
 | 
        
           |  |  | 103 | register unsigned char bit=0;
 | 
        
           |  |  | 104 |   | 
        
           |  |  | 105 | 	for(bit=0; bit<=7; bit++)
 | 
        
           |  |  | 106 | 	  {
 | 
        
           |  |  | 107 | 	      if( data & 0x80 ) { SDA_1(); } else { SDA_0(); }
 | 
        
           |  |  | 108 | 	      SCL_1();
 | 
        
           |  |  | 109 | 	      delay(I2C_DELAY);
 | 
        
           |  |  | 110 | 	      SCL_0();
 | 
        
           |  |  | 111 | 	      delay(I2C_DELAY);
 | 
        
           |  |  | 112 | 	      data = (data<<1);
 | 
        
           |  |  | 113 | 	  }
 | 
        
           |  |  | 114 | 	/* Look for AKNOWLEDGE */
 | 
        
           |  |  | 115 | 	RELEASE_I2C_BUS();
 | 
        
           |  |  | 116 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 117 |   | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 | 	if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) )
 | 
        
           |  |  | 120 | 	 {
 | 
        
           |  |  | 121 | 	     SCL_0();
 | 
        
           |  |  | 122 | 	     delay(I2C_DELAY);
 | 
        
           |  |  | 123 | 	 }
 | 
        
           |  |  | 124 | 	else{
 | 
        
           |  |  | 125 | 		 delay(I2C_TIMEOUT);
 | 
        
           |  |  | 126 | 		 if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) )
 | 
        
           |  |  | 127 | 		  {
 | 
        
           |  |  | 128 | 		     SCL_0();
 | 
        
           |  |  | 129 | 		     delay(I2C_DELAY);
 | 
        
           |  |  | 130 | 		  }
 | 
        
           |  |  | 131 | 		 else { return(I2C_ERROR_DEVICE_NOT_RESPONDING); }
 | 
        
           |  |  | 132 | 	    }
 | 
        
           |  |  | 133 |   | 
        
           |  |  | 134 |   | 
        
           |  |  | 135 | 	if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) ) 
 | 
        
           |  |  | 136 | 	 { 
 | 
        
           |  |  | 137 | 	       delay(I2C_TIMEOUT);
 | 
        
           |  |  | 138 | 	       if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) ) { return(I2C_ERROR_DEVICE_BUSY); }
 | 
        
           |  |  | 139 | 	 }   
 | 
        
           |  |  | 140 |   | 
        
           |  |  | 141 |   | 
        
           |  |  | 142 | return(I2C_NO_ERROR);	  
 | 
        
           |  |  | 143 | }
 | 
        
           |  |  | 144 | /*#################################################################################################*/
 | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 | unsigned char i2c_receive(unsigned char ack)
 | 
        
           |  |  | 147 | {
 | 
        
           |  |  | 148 | register unsigned char bit=0, data=0;
 | 
        
           |  |  | 149 |   | 
        
           |  |  | 150 | 	SDA_1();
 | 
        
           |  |  | 151 | 	for(bit=0; bit<=7; bit++)
 | 
        
           |  |  | 152 | 	  {
 | 
        
           |  |  | 153 | 	      SCL_1();
 | 
        
           |  |  | 154 | 	      delay(I2C_DELAY);
 | 
        
           |  |  | 155 | 	      data = (data<<1);
 | 
        
           |  |  | 156 | 	      if( bit_is_set(I2C_SDA_PIN_REG, SDA_PIN) ) { data++; }
 | 
        
           |  |  | 157 | 	      SCL_0();
 | 
        
           |  |  | 158 | 	      delay(I2C_DELAY);
 | 
        
           |  |  | 159 | 	  }
 | 
        
           |  |  | 160 |   | 
        
           |  |  | 161 | 	/* if CONTINUE then send AKNOWLEDGE else if QUIT do not send AKNOWLEDGE (send Nack) */	     
 | 
        
           |  |  | 162 | 	if(ack==I2C_CONTINUE) { SDA_0(); }  else { SDA_1(); }
 | 
        
           |  |  | 163 | 	SCL_1();
 | 
        
           |  |  | 164 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 165 | 	SCL_0();
 | 
        
           |  |  | 166 | 	delay(I2C_DELAY);
 | 
        
           |  |  | 167 |   | 
        
           |  |  | 168 | return data;
 | 
        
           |  |  | 169 | }
 | 
        
           |  |  | 170 | /*#################################################################################################*/
 | 
        
           |  |  | 171 |   | 
        
           |  |  | 172 |   |