Subversion Repositories svnkaklik

Compare Revisions

Ignore whitespace Rev 409 → Rev 410

/programy/C/avr/SFR08/i2c.c
0,0 → 1,172
 
/****************************************************************************
Title : C file for the I2C FUNCTIONS library (i2c.c)
Author: Chris efstathiou hendrix@otenet.gr
Date: 13/Jul/2002
Software: AVR-GCC with AVR-AS
Target: any AVR device
Comments: This software is FREE.
 
*****************************************************************************/
 
#include <io.h>
#include "i2c.h"
 
#ifndef CONCAT1
#define CONCAT1(a, b) CONCAT2(a, b)
#endif
 
#ifndef CONCAT2
#define CONCAT2(a, b) a ## b
#endif
 
 
/* Conversion of microseconds to the right value for the delay function */
#define I2C_DELAY ( (I2C_DELAY_TIME*(F_CPU/60000))/100 )
#define I2C_TIMEOUT ( (I2C_TIMEOUT_TIME*(F_CPU/60000))/100 )
 
/* Register name forming */
#define I2C_SDA_OUT_REG CONCAT1(PORT, I2C_SDA_PORT)
#define I2C_SCL_OUT_REG CONCAT1(PORT, I2C_SCL_PORT)
#define I2C_SDA_DDR_REG CONCAT1(DDR, I2C_SDA_PORT)
#define I2C_SCL_DDR_REG CONCAT1(DDR, I2C_SCL_PORT)
#define I2C_SDA_PIN_REG CONCAT1(PIN, I2C_SDA_PORT)
#define I2C_SCL_PIN_REG CONCAT1(PIN, I2C_SCL_PORT)
 
/* Conversion of microseconds to the right value for the delay function */
#define I2C_DELAY ( (I2C_DELAY_TIME*(F_CPU/60000))/100 )
#define I2C_TIMEOUT ( (I2C_TIMEOUT_TIME*(F_CPU/60000))/100 )
 
/* Pin states */
#define SCL_1() cbi(I2C_SCL_DDR_REG, SCL_PIN)
#define SCL_0() sbi(I2C_SCL_DDR_REG, SCL_PIN)
#define SDA_1() cbi(I2C_SDA_DDR_REG, SDA_PIN)
#define SDA_0() sbi(I2C_SDA_DDR_REG, SDA_PIN)
 
#define RELEASE_I2C_BUS() { SCL_1(); SDA_1(); }
 
/*#################################################################################################*/
 
static void delay(unsigned long us)
{
 
while ( us ) { us--; } /* 6 cpu cycles per loop */
}
/*#################################################################################################*/
 
void i2c_init(void)
{
cbi(I2C_SDA_OUT_REG, SDA_PIN);
cbi(I2C_SCL_OUT_REG, SCL_PIN);
RELEASE_I2C_BUS();
delay(I2C_TIMEOUT);
i2c_start();
delay(I2C_TIMEOUT);
i2c_stop();
delay(I2C_TIMEOUT);
 
 
return;
}
/*#################################################################################################*/
 
void i2c_start(void)
{
RELEASE_I2C_BUS();
delay(I2C_DELAY);
SDA_0();
delay(I2C_DELAY);
SCL_0();
delay(I2C_DELAY);
 
return;
}
/*#################################################################################################*/
 
void i2c_stop(void)
{
SDA_0();
SCL_1();
delay(I2C_DELAY);
SDA_1();
delay(I2C_DELAY);
SCL_0();
delay(I2C_DELAY);
 
return;
}
/*#################################################################################################*/
 
unsigned char i2c_transmit(unsigned char data)
{
register unsigned char bit=0;
 
for(bit=0; bit<=7; bit++)
{
if( data & 0x80 ) { SDA_1(); } else { SDA_0(); }
SCL_1();
delay(I2C_DELAY);
SCL_0();
delay(I2C_DELAY);
data = (data<<1);
}
/* Look for AKNOWLEDGE */
RELEASE_I2C_BUS();
delay(I2C_DELAY);
 
 
if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) )
{
SCL_0();
delay(I2C_DELAY);
}
else{
delay(I2C_TIMEOUT);
if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) )
{
SCL_0();
delay(I2C_DELAY);
}
else { return(I2C_ERROR_DEVICE_NOT_RESPONDING); }
}
 
 
if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) )
{
delay(I2C_TIMEOUT);
if( bit_is_clear(I2C_SDA_PIN_REG, SDA_PIN) ) { return(I2C_ERROR_DEVICE_BUSY); }
}
 
 
return(I2C_NO_ERROR);
}
/*#################################################################################################*/
 
unsigned char i2c_receive(unsigned char ack)
{
register unsigned char bit=0, data=0;
 
SDA_1();
for(bit=0; bit<=7; bit++)
{
SCL_1();
delay(I2C_DELAY);
data = (data<<1);
if( bit_is_set(I2C_SDA_PIN_REG, SDA_PIN) ) { data++; }
SCL_0();
delay(I2C_DELAY);
}
/* if CONTINUE then send AKNOWLEDGE else if QUIT do not send AKNOWLEDGE (send Nack) */
if(ack==I2C_CONTINUE) { SDA_0(); } else { SDA_1(); }
SCL_1();
delay(I2C_DELAY);
SCL_0();
delay(I2C_DELAY);
 
return data;
}
/*#################################################################################################*/