|
|
|
|
@ -5,33 +5,34 @@
|
|
|
|
|
|
|
|
|
|
#include "i2c_simple.h"
|
|
|
|
|
|
|
|
|
|
#define I2C_WAIT() while(!(TWCR & _BV(TWINT)))
|
|
|
|
|
|
|
|
|
|
void i2c_init()
|
|
|
|
|
{
|
|
|
|
|
TWBR = 32;//bit rate
|
|
|
|
|
TWSR = 0;//Prescaler
|
|
|
|
|
|
|
|
|
|
TWAR = 0x80;//our address 1000 000, don't listen to general call
|
|
|
|
|
TWAMR = 0;
|
|
|
|
|
// TWAR = 0x80;//our address 1000 000, don't listen to general call
|
|
|
|
|
// TWAMR = 0;
|
|
|
|
|
|
|
|
|
|
TWCR = TWEA | TWEN;/* TWINT clear -> we must do something; unset TWSTA manually!, TWSTO */
|
|
|
|
|
TWCR = _BV(TWEA) | _BV(TWEN);/* _BV(TWINT) clear -> we must do something; unset _BV(TWSTA) manually!, _BV(TWSTO) */
|
|
|
|
|
//TWDR - data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data)
|
|
|
|
|
{
|
|
|
|
|
TWCR &= ~TWSTO;
|
|
|
|
|
TWCR |= TWINT | TWSTA;
|
|
|
|
|
while(~TWCR & TWINT) {;}/* get bus access */
|
|
|
|
|
TWCR |= _BV(TWINT) | _BV(TWSTA);
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
/* no error possible */
|
|
|
|
|
|
|
|
|
|
TWDR = addr | 1;
|
|
|
|
|
TWCR &= ~(TWSTA | TWSTO);
|
|
|
|
|
TWCR |= TWINT;
|
|
|
|
|
while(~TWCR & TWINT) {;}/* transmit address */
|
|
|
|
|
TWCR &= ~(_BV(TWSTA));
|
|
|
|
|
TWCR |= _BV(TWINT);
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
/* possible results: ACK, NAK, abitration lost */
|
|
|
|
|
if(TW_STATUS == TW_MR_SLA_NACK)
|
|
|
|
|
{
|
|
|
|
|
TWCR |= TWINT | TWSTO;
|
|
|
|
|
TWCR |= _BV(TWINT) | _BV(TWSTO);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if(TW_STATUS == TW_MR_ARB_LOST) {return 0;}
|
|
|
|
|
@ -39,37 +40,36 @@ uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data)
|
|
|
|
|
uint8_t done = 0;
|
|
|
|
|
while(done + 1 < len)
|
|
|
|
|
{
|
|
|
|
|
TWCR |= TWEA | TWINT;/* send ack after byte */
|
|
|
|
|
while(~TWCR & TWINT) {;}/* read data */
|
|
|
|
|
TWCR |= _BV(TWEA) | _BV(TWINT);/* send ack after byte */
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
data[done] = TWDR;
|
|
|
|
|
done++;
|
|
|
|
|
TWCR |= TWINT;
|
|
|
|
|
TWCR |= _BV(TWINT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TWCR &= ~TWEA;
|
|
|
|
|
TWCR |= TWINT;/* send nak after byte */
|
|
|
|
|
while(~TWCR & TWINT) {;}/* read data */
|
|
|
|
|
TWCR &= ~_BV(TWEA);
|
|
|
|
|
TWCR |= _BV(TWINT);/* send nak after byte */
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
data[done] = TWDR;
|
|
|
|
|
done++;
|
|
|
|
|
TWCR |= TWINT | TWSTO;
|
|
|
|
|
TWCR |= _BV(TWINT) | _BV(TWSTO);
|
|
|
|
|
return done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t i2c_write_i(uint8_t addr, uint8_t len, uint8_t *data, uint8_t stop)
|
|
|
|
|
{
|
|
|
|
|
TWCR &= ~TWSTO;
|
|
|
|
|
TWCR |= TWINT | TWSTA;
|
|
|
|
|
while(~TWCR & TWINT) {;}/* get bus access */
|
|
|
|
|
TWCR |= _BV(TWINT) | _BV(TWSTA);
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
/* no error possible */
|
|
|
|
|
|
|
|
|
|
TWDR = addr;
|
|
|
|
|
TWCR &= ~(TWSTA | TWSTO);
|
|
|
|
|
TWCR |= TWINT;
|
|
|
|
|
while(~TWCR & TWINT) {;}/* transmit address */
|
|
|
|
|
TWCR &= ~(_BV(TWSTA));
|
|
|
|
|
TWCR |= _BV(TWINT);
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
/* possible results: ACK, NAK, abitration lost */
|
|
|
|
|
if(TW_STATUS == TW_MT_SLA_NACK)
|
|
|
|
|
{
|
|
|
|
|
TWCR |= TWINT | TWSTO;
|
|
|
|
|
TWCR |= _BV(TWINT) | _BV(TWSTO);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if(TW_STATUS == TW_MT_ARB_LOST) {return 0;}
|
|
|
|
|
@ -78,19 +78,19 @@ uint8_t i2c_write_i(uint8_t addr, uint8_t len, uint8_t *data, uint8_t stop)
|
|
|
|
|
while(done < len)
|
|
|
|
|
{
|
|
|
|
|
TWDR = data[done];
|
|
|
|
|
TWCR |= TWINT;
|
|
|
|
|
while(~TWCR & TWINT) {;}/* write data */
|
|
|
|
|
TWCR |= _BV(TWINT);
|
|
|
|
|
I2C_WAIT();
|
|
|
|
|
/* possible results: ACK, NAK, abitration lost */
|
|
|
|
|
if(TW_STATUS == TW_MT_DATA_NACK)
|
|
|
|
|
{
|
|
|
|
|
TWCR |= TWINT | TWSTO;
|
|
|
|
|
TWCR |= _BV(TWINT) | _BV(TWSTO);
|
|
|
|
|
return done;
|
|
|
|
|
}
|
|
|
|
|
else if(TW_STATUS == TW_MT_ARB_LOST) {return done;}
|
|
|
|
|
done++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(stop) {TWCR |= TWINT | TWSTO;}
|
|
|
|
|
if(stop) {TWCR |= _BV(TWINT) | _BV(TWSTO);}
|
|
|
|
|
return done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|